diff --git a/modules/expirycheck/default-disable b/modules/expirycheck/default-disable
new file mode 100644
index 0000000000000000000000000000000000000000..fa0bd82e2df7bd79d57593d35bc53c1f9d3ef71f
--- /dev/null
+++ b/modules/expirycheck/default-disable
@@ -0,0 +1,3 @@
+This file indicates that the default state of this module
+is disabled. To enable, create a file named enable in the
+same directory as this file.
diff --git a/modules/expirycheck/dictionaries/warning.definition.json b/modules/expirycheck/dictionaries/warning.definition.json
new file mode 100644
index 0000000000000000000000000000000000000000..8201900038bf69ce662b9491653a01c113ce5ea6
--- /dev/null
+++ b/modules/expirycheck/dictionaries/warning.definition.json
@@ -0,0 +1,35 @@
+{
+	"access_denied": {
+		"en": "You do not have access to this service"
+	},
+	"no_access_to": {
+		"en": "Your account %NETID% has expired, access denied!"
+	},
+	"contact_home": {
+		"en": "Access to services is controlled by your home organization. Please contact your local IT support for questions."
+	},
+	"expiry_date_text": {
+		"en": "Expiration date:"
+	},
+	"warning_header": {
+		"en": "Warning, your account %NETID% will expire in %DAYSLEFT% %DAYS%!"
+	},
+	"warning_header_today": {
+		"en": "Warning, your account %NETID% will expire today!"
+	},
+	"warning": {
+		"en": "Warning, your account %NETID% will expire in %DAYSLEFT% %DAYS%!"
+	},
+	"warning_today": {
+		"en": "Warning, your account %NETID% will expire today!"
+	},
+	"day": {
+		"en": "day"
+	},
+	"days": {
+		"en": "days"
+	},
+	"btn_continue": {
+		"en": "I am aware of this, continue..."
+	}
+}
diff --git a/modules/expirycheck/dictionaries/warning.translation.json b/modules/expirycheck/dictionaries/warning.translation.json
new file mode 100644
index 0000000000000000000000000000000000000000..195225099e492f8344b250c20932ba419cbcbd49
--- /dev/null
+++ b/modules/expirycheck/dictionaries/warning.translation.json
@@ -0,0 +1,46 @@
+{
+	"access_denied": {
+		"en": "You do not have access to this service",
+		"sl": "Dostop do storitve zavrnjen."
+	},
+	"no_access_to": {
+		"en": "Your account %NETID% has expired, access denied!",
+		"sl": "Dostop zavrnjen, ker je va\u0161e uporabni\u0161ko (NetID) %NETID% ime poteklo!"
+	},
+	"contact_home": {
+		"en": "Access to services is controlled by your home organization. Please contact your local IT support for questions.",
+		"sl": "Mo\u017enost dostopa do storitve ureja va\u0161a doma\u010da organizacija. Obrnite se na njihov oddelek za pomo\u010d uporabnikom."
+	},
+	"expiry_date_text": {
+		"en": "Expiration date:",
+		"sl": "Datum poteka:"
+	},
+	"warning_header": {
+		"en": "Warning, your account %NETID% will expire in %DAYSLEFT% %DAYS%!",
+		"sl": "Pozor! Va\u0161e uporabni\u0161ko ime (NetID) %NETID% bo poteklo \u010dez %DAYSLEFT% %DAYS%!"
+	},
+	"warning_header_today": {
+		"en": "Warning, your account %NETID% will expire today!",
+		"sl": "Pozor! Va\u0161e uporabni\u0161ko ime (NetID) %NETID% pote\u010de danes!"
+	},
+	"warning": {
+		"en": "Warning, your account %NETID% will expire in %DAYSLEFT% %DAYS%!",
+		"sl": "Pozor! Va\u0161e uporabni\u0161ko ime (NetID) %NETID% bo poteklo \u010dez %DAYSLEFT% %DAYS%!"
+	},
+	"warning_today": {
+		"en": "Warning, your account %NETID% will expire today!",
+		"sl": "Pozor! Va\u0161e uporabni\u0161ko ime (NetID) %NETID% pote\u010de danes!"
+	},
+	"day": {
+		"en": "day",
+		"sl": "dan"
+	},
+	"days": {
+		"en": "days",
+		"sl": "dni"
+	},
+	"btn_continue": {
+		"en": "I am aware of this, continue..." ,
+		"sl": "Zavedam se tega, nadaljuj..."
+	}
+}
diff --git a/modules/expirycheck/docs/expirycheck.txt b/modules/expirycheck/docs/expirycheck.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fecf3b6e47c1572a6875542b45f0d0b85f0263c8
--- /dev/null
+++ b/modules/expirycheck/docs/expirycheck.txt
@@ -0,0 +1,48 @@
+expirycheck module
+==================
+
+The expirycheck module validates user's expiry date attribute by showing
+warning to the user whose NetID is about to expire or denying access if NetID
+has already expired.
+
+The expirycheck module is implemented as an Authentication Processing Filter.
+That means it can be configured in the global config.php file or the SP remote
+or IdP hosted metadata.
+
+It is recommended to run the expirycheck module at the IdP, and configure the
+filter to run before all the other filters you may have enabled.
+
+How to setup the expirycheck module
+-----------------------------------
+
+First you need to enable the expirycheck module, touch an `enable` file, in the
+expirycheck module:
+
+    touch modules/expirycheck/enable
+
+Then you need to set filter parameters in your config.php file.
+
+Example:
+
+	10 => array(
+		'class' 	  => 'expirycheck:ExpiryDate',
+		'netid_attr' 	  => 'eduPersonPrincipalName',
+		'expirydate_attr' => 'schacExpiryDate',
+		'warndaysbefore'  => '60',
+		'date_format' 	  => 'd.m.Y',
+	),
+
+
+Parameter netid_attr represents (ldap) attribute name which has user's NetID stored in it,
+parameter expirydate_attr represents (ldap) attribute name which has user's expiry date
+(date must be formated as YYYYMMDDHHMMSSZ, e.g. 20111011235959Z) stored in it. Those two
+attributes needs to be part of the attribute set, which is retrived from ldap during
+authentication process.
+Parameter warndaysbefore set as a number, which represents how many days before expiry
+date the "about to expire" warning will show to the user.
+Parameter date_format defines date representation format. PHP Date() syntax
+is used. More info: http://php.net/manual/en/function.date.php
+
+P.S.
+
+Comments and bug reports please send to Alex MihiÄŤinac <alexm@arnes.si>
diff --git a/modules/expirycheck/lib/Auth/Process/ExpiryDate.php b/modules/expirycheck/lib/Auth/Process/ExpiryDate.php
new file mode 100644
index 0000000000000000000000000000000000000000..65b8395f5df48636c065bda1350cd9291d66bffe
--- /dev/null
+++ b/modules/expirycheck/lib/Auth/Process/ExpiryDate.php
@@ -0,0 +1,161 @@
+<?php
+
+/**
+ * Filter which show "about to expire" warning or deny access if netid is expired.
+ *
+ * Based on preprodwarning module by rnd.feide.no
+ *
+ * <code>
+ * // show about2xpire warning or deny access if netid is expired
+ * 10 => array(
+ *     'class' => 'expirycheck:ExpiryDate',
+ *     'netid_attr' => 'eduPersonPrincipalName',
+ *     'expirydate_attr' => 'schacExpiryDate',
+ *     'warndaysbefore' => '60',
+ *     'date_format' => 'd.m.Y', # php date syntax
+ * ),
+ * </code>
+ *
+ * @author Alex MihiÄŤinac, ARNES. <alexm@arnes.si>
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+
+class sspmod_expirycheck_Auth_Process_ExpiryDate extends SimpleSAML_Auth_ProcessingFilter {
+
+	private $warndaysbefore = 0;
+	private $netid_attr = NULL;
+	private $expirydate_attr = NULL;
+	private $date_format = 'd.m.Y';
+
+
+	/**
+	 * Initialize this filter.
+	 *
+	 * @param array $config  Configuration information about this filter.
+	 * @param mixed $reserved  For future use.
+	 */
+	public function __construct($config, $reserved) {
+		parent::__construct($config, $reserved);
+
+		assert('is_array($config)');
+
+		if (array_key_exists('warndaysbefore', $config)) {
+			$this->warndaysbefore = $config['warndaysbefore'];
+			if (!is_string($this->warndaysbefore)) {
+				throw new Exception('Invalid value for number of days given to expirycheck::ExpiryDate filter.');
+			}
+		}
+
+		if (array_key_exists('netid_attr', $config)) {
+			$this->netid_attr = $config['netid_attr'];
+			if (!is_string($this->netid_attr)) {
+				throw new Exception('Invalid attribute name given as eduPersonPrincipalName to expirycheck::ExpiryDate filter.');
+			}
+		}
+
+		if (array_key_exists('expirydate_attr', $config)) {
+			$this->expirydate_attr = $config['expirydate_attr'];
+			if (!is_string($this->expirydate_attr)) {
+				throw new Exception('Invalid attribute name given as schacExpiryDate to expirycheck::ExpiryDate filter.');
+			}
+		}
+
+		if (array_key_exists('date_format', $config)) {
+			$this->date_format = $config['date_format'];
+			if (!is_string($this->date_format)) {
+				throw new Exception('Invalid date format given to expirycheck::ExpiryDate filter.');
+			}
+		}
+	}
+
+	/**
+	 * Show expirational warning if remaining days is equal or under defined $warndaysbefore
+	 * @param integer $expireOnDate
+	 * @param integer $warndaysbefore
+	 * @return bool
+	 *
+	 */
+	public function shWarning(&$state, $expireOnDate, $warndaysbefore) {
+		#date_default_timezone_set('Europe/Ljubljana');
+		$now = time();
+		$end = $expireOnDate;
+
+		if ($expireOnDate >= $now) {
+			$days = (int)(($end - $now) / (24*60*60));
+			if ($days <= $warndaysbefore) {
+				$state['daysleft'] = $days;
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 *  Check if given date is older than today
+	 *  @param integer $expireOnDate
+	 *  @return bool
+	 *
+	 */
+	public function checkDate($expireOnDate) {
+		$now = time();
+		$end = $expireOnDate;
+
+		if ($now <= $end) {
+			return true;
+		} else {
+			return false;
+		}
+
+	}
+
+	/**
+	 * Apply filter
+	 *
+	 * @param array &$state  The current state.
+	 */
+	public function process(&$state) {
+		/*
+		 * UTC format: 20090527080352Z
+		 */
+		$netId = $state['Attributes'][$this->netid_attr][0];
+		$expireOnDate = strtotime($state['Attributes'][$this->expirydate_attr][0]);
+
+		if (self::shWarning(&$state, $expireOnDate, $this->warndaysbefore)) {
+			assert('is_array($state)');
+			if (isset($state['isPassive']) && $state['isPassive'] === TRUE) {
+				/* We have a passive request. Skip the warning. */
+				return;
+			}
+
+			SimpleSAML_Logger::warning('expirycheck: NetID ' . $netId .
+			                           ' is about to expire!');
+
+			/* Save state and redirect. */
+			$state['expireOnDate'] = date($this->date_format, $expireOnDate);
+			$state['netId'] = $netId;
+			$id = SimpleSAML_Auth_State::saveState($state, 'expirywarning:about2expire');
+			$url = SimpleSAML_Module::getModuleURL('expirycheck/about2expire.php');
+			SimpleSAML_Utilities::redirect($url, array('StateId' => $id));
+		}
+
+		if (!self::checkDate($expireOnDate)) {
+			SimpleSAML_Logger::error('expirycheck: NetID ' . $netId .
+			                         ' has expired [' . date($this->date_format, $expireOnDate) . ']. Access denied!');
+			$globalConfig = SimpleSAML_Configuration::getInstance();
+
+			/* Save state and redirect. */
+			$state['expireOnDate'] = date($this->date_format, $expireOnDate);
+			$state['netId'] = $netId;
+			$id = SimpleSAML_Auth_State::saveState($state, 'expirywarning:expired');
+			$url = SimpleSAML_Module::getModuleURL('expirycheck/expired.php');
+			SimpleSAML_Utilities::redirect($url, array('StateId' => $id));
+
+		}
+	}
+
+
+}
+
+
+?>
diff --git a/modules/expirycheck/templates/about2expire.php b/modules/expirycheck/templates/about2expire.php
new file mode 100644
index 0000000000000000000000000000000000000000..eadb4bb86fe2dc46fe33871aa1c6db61214db9ae
--- /dev/null
+++ b/modules/expirycheck/templates/about2expire.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * Template form for giving consent.
+ *
+ * Parameters:
+ * - 'srcMetadata': Metadata/configuration for the source.
+ * - 'dstMetadata': Metadata/configuration for the destination.
+ * - 'yesTarget': Target URL for the yes-button. This URL will receive a POST request.
+ * - 'yesData': Parameters which should be included in the yes-request.
+ * - 'noTarget': Target URL for the no-button. This URL will receive a GET request.
+ * - 'noData': Parameters which should be included in the no-request.
+ * - 'attributes': The attributes which are about to be released.
+ * - 'sppp': URL to the privacy policy of the destination, or FALSE.
+ *
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+
+
+//$this->data['header'] = $this->t('{expirycheck:warning:warning_header}');
+
+# netid will expire today
+if ($this->data['daysleft'] == 0) {
+	$this->data['header'] = $this->t('{expirycheck:warning:warning_header_today}', array(
+				'%NETID%' => htmlspecialchars($this->data['netId'])
+			));
+
+	$warning = $this->t('{expirycheck:warning:warning_today}', array(
+				'%NETID%' => htmlspecialchars($this->data['netId'])
+			));
+
+}
+# netid will expire in one day
+elseif ($this->data['daysleft'] == 1) {
+
+	$this->data['header'] = $this->t('{expirycheck:warning:warning_header}', array(
+				'%NETID%' => htmlspecialchars($this->data['netId']),
+				'%DAYS%' => $this->t('{expirycheck:warning:day}'),
+				'%DAYSLEFT%' => htmlspecialchars($this->data['daysleft']),
+			));
+
+	$warning = $this->t('{expirycheck:warning:warning}', array(
+				'%NETID%' => htmlspecialchars($this->data['netId']),
+				'%DAYS%' => $this->t('{expirycheck:warning:day}'),
+				'%DAYSLEFT%' => htmlspecialchars($this->data['daysleft']),
+			));
+
+}
+# netid will expire in next <daysleft> days
+else {
+	$this->data['header'] = $this->t('{expirycheck:warning:warning_header}', array(
+				'%NETID%' => htmlspecialchars($this->data['netId']),
+				'%DAYS%' => $this->t('{expirycheck:warning:days}'),
+				'%DAYSLEFT%' => htmlspecialchars($this->data['daysleft']),
+			));
+
+	$warning = $this->t('{expirycheck:warning:warning}', array(
+				'%NETID%' => htmlspecialchars($this->data['netId']),
+				'%DAYS%' => $this->t('{expirycheck:warning:days}'),
+				'%DAYSLEFT%' => htmlspecialchars($this->data['daysleft']),
+			));
+
+
+}
+
+//$this->data['header'] = str_replace("%DAYSLEFT%", $this->data['daysleft'], str_replace("%NETID%", $this->data['netId'], $this->t('{expirycheck:warning:warning_header}')));
+$this->data['autofocus'] = 'yesbutton';
+
+$this->includeAtTemplateBase('includes/header.php');
+
+?>
+
+<form style="display: inline; margin: 0px; padding: 0px" action="<?php echo htmlspecialchars($this->data['yesTarget']); ?>">
+
+	<?php
+		// Embed hidden fields...
+		foreach ($this->data['yesData'] as $name => $value) {
+			echo('<input type="hidden" name="' . htmlspecialchars($name) . '" value="' . htmlspecialchars($value) . '" />');
+		}
+	?>
+	<h3><?php echo $warning; ?></h3>
+	<p><?php echo $this->t('{expirycheck:warning:expiry_date_text}') . " " . $this->data['expireOnDate']; ?></p>
+
+	<input type="submit" name="yes" id="yesbutton" value="<?php echo htmlspecialchars($this->t('{expirycheck:warning:btn_continue}')) ?>" />
+
+</form>
+
+
+<?php
+
+$this->includeAtTemplateBase('includes/footer.php');
+?>
diff --git a/modules/expirycheck/templates/expired.php b/modules/expirycheck/templates/expired.php
new file mode 100644
index 0000000000000000000000000000000000000000..0edd9aaad63e7fad059d9b1b935dab77ca7e0291
--- /dev/null
+++ b/modules/expirycheck/templates/expired.php
@@ -0,0 +1,12 @@
+<?php
+$this->data['header'] = $this->t('{expirycheck:warning:access_denied}');
+$this->includeAtTemplateBase('includes/header.php');
+?>
+
+		<h2><?php echo $this->t('{expirycheck:warning:access_denied}');?></h2>
+		<p><?php echo $this->t('{expirycheck:warning:no_access_to}', array('%NETID%' => htmlspecialchars($this->data['netId'])));?></p> 
+		<p><?php echo $this->t('{expirycheck:warning:expiry_date_text}');?> <b><?php echo htmlspecialchars($this->data['expireOnDate']);?></b></p>
+		<p><?php echo $this->t('{expirycheck:warning:contact_home}');?></p>
+<?php
+$this->includeAtTemplateBase('includes/footer.php');
+?>
diff --git a/modules/expirycheck/www/about2expire.php b/modules/expirycheck/www/about2expire.php
new file mode 100644
index 0000000000000000000000000000000000000000..c69624723ac223fa571725031458ce2581eb1ba2
--- /dev/null
+++ b/modules/expirycheck/www/about2expire.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * about2expire.php
+ *
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+
+SimpleSAML_Logger::info('expirycheck - User has been warned that NetID is near to expirational date.');
+
+if (!array_key_exists('StateId', $_REQUEST)) {
+	throw new SimpleSAML_Error_BadRequest('Missing required StateId query parameter.');
+}
+
+$id = $_REQUEST['StateId'];
+$state = SimpleSAML_Auth_State::loadState($id, 'expirywarning:about2expire');
+
+
+if (array_key_exists('yes', $_REQUEST)) {
+	/* The user has pressed the yes-button. */
+	SimpleSAML_Auth_ProcessingChain::resumeProcessing($state);
+}
+
+$globalConfig = SimpleSAML_Configuration::getInstance();
+
+$t = new SimpleSAML_XHTML_Template($globalConfig, 'expirycheck:about2expire.php');
+$t->data['yesTarget'] = SimpleSAML_Module::getModuleURL('expirycheck/about2expire.php');
+$t->data['yesData'] = array('StateId' => $id);
+$t->data['daysleft'] = $state['daysleft'];
+$t->data['expireOnDate'] = $state['expireOnDate'];
+$t->data['netId'] = $state['netId'];
+$t->show();
+
+
+?>
diff --git a/modules/expirycheck/www/expired.php b/modules/expirycheck/www/expired.php
new file mode 100644
index 0000000000000000000000000000000000000000..9b94cadbcec3a7df15f5e88aed680b7539571e69
--- /dev/null
+++ b/modules/expirycheck/www/expired.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * about2expire.php
+ *
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+
+SimpleSAML_Logger::info('expirycheck - User has been warned that NetID is near to expirational date.');
+
+if (!array_key_exists('StateId', $_REQUEST)) {
+	throw new SimpleSAML_Error_BadRequest('Missing required StateId query parameter.');
+}
+
+$id = $_REQUEST['StateId'];
+$state = SimpleSAML_Auth_State::loadState($id, 'expirywarning:expired');
+
+$globalConfig = SimpleSAML_Configuration::getInstance();
+
+$t = new SimpleSAML_XHTML_Template($globalConfig, 'expirycheck:expired.php');
+$t->data['expireOnDate'] = $state['expireOnDate'];
+$t->data['netId'] = $state['netId'];
+$t->show();
+
+
+?>