diff --git a/modules/radius/docs/radius.txt b/modules/radius/docs/radius.txt
index a390ac83067a9a9c317f97077b549948f810f29f..ae5e70d3afa29370e7592adad844d2f22cc3558c 100644
--- a/modules/radius/docs/radius.txt
+++ b/modules/radius/docs/radius.txt
@@ -39,9 +39,9 @@ authentication source which uses the `radius:Radius` module to
 
         /*
          * The number of times we should retry connections to the RADIUS server.
-	 * Please note that retries would be attempted with each server before
-	 * trying with the next server in the queue, so if you want not to wait
-	 * before trying the next server, retries should be set to 1.
+         * Please note that retries would be attempted with each server before
+         * trying with the next server in the queue, so if you want not to wait
+         * before trying the next server, retries should be set to 1.
          * Optional, defaults to 3 attempts.
          */
         'retries' => 3,
@@ -52,6 +52,15 @@ authentication source which uses the `radius:Radius` module to
          */
         'nas_identifier' => 'client.example.org',
 
+        /*
+         * An optional realm that will be suffixed to the username entered
+         * by the user. When set to "example.edu", and the user enters
+         * "bob" as their username, the radius server will be queried for
+         * the username "bob@example.edu".
+         * Optional, defaults to NULL.
+         */
+        'realm' => 'example.edu',
+
         /*
          * The attribute name we should store the username in. Ths username
          * will not be saved in any attribute if this is NULL.
@@ -71,7 +80,7 @@ from the RADIUS server.
 
 The code expects one vendor-attribute with a specific vendor and a specific
 vendor attribute type for each user attribute. The vendor-attribute must
-contain a value on the form <name>=<value>.
+contain a value of the form `&lt;name&gt;=&lt;value&gt;`.
 
 The following configuration options are available for user attributes:
 
diff --git a/modules/radius/lib/Auth/Source/Radius.php b/modules/radius/lib/Auth/Source/Radius.php
index fbe719126bc23bba6afe8269b7bf6a88720b5ba0..994780686e8f94c63a2c5942c2f6b1a29129009f 100644
--- a/modules/radius/lib/Auth/Source/Radius.php
+++ b/modules/radius/lib/Auth/Source/Radius.php
@@ -7,209 +7,230 @@
  *
  * @package SimpleSAMLphp
  */
-class sspmod_radius_Auth_Source_Radius extends sspmod_core_Auth_UserPassBase {
-
-	/**
-	 * The list of radius servers to use.
-	 */
-	private $servers;
-
-	/**
-	 * The hostname of the radius server.
-	 */
-	private $hostname;
-
-	/**
-	 * The port of the radius server.
-	 */
-	private $port;
-
-	/**
-	 * The secret used when communicating with the radius server.
-	 */
-	private $secret;
-
-	/**
-	 * The timeout for contacting the radius server.
-	 */
-	private $timeout;
-
-	/**
-	 * The number of retries which should be attempted.
-	 */
-	private $retries;
-
-	/**
-	 * The attribute name where the username should be stored.
-	 */
-	private $usernameAttribute;
-
-	/**
-	 * The vendor for the RADIUS attributes we are interrested in.
-	 */
-	private $vendor;
-
-	/**
-	 * The vendor-specific attribute for the RADIUS attributes we are interrested in.
-	 */
-	private $vendorType;
-	/**
-	 * The NAS-Identifier that should be set in Access-Request packets.
-	 */
-	private $nasIdentifier;
-
-	/**
-	 * Constructor for this authentication source.
-	 *
-	 * @param array $info  Information about this authentication source.
-	 * @param array $config  Configuration.
-	 */
-	public function __construct($info, $config) {
-		assert('is_array($info)');
-		assert('is_array($config)');
-
-		// Call the parent constructor first, as required by the interface
-		parent::__construct($info, $config);
-
-		// Parse configuration.
-		$config = SimpleSAML_Configuration::loadFromArray($config,
-			'Authentication source ' . var_export($this->authId, TRUE));
-
-		$this->servers = $config->getArray('servers', array());
-		/* For backwards compatibility. */
-		if (empty($this->servers)) {
-			$this->hostname = $config->getString('hostname');
-			$this->port = $config->getIntegerRange('port', 1, 65535, 1812);
-			$this->secret = $config->getString('secret');
-			$this->servers[] = array('hostname' => $this->hostname,
-									 'port' => $this->port,
-									 'secret' => $this->secret);
-		}
-		$this->timeout = $config->getInteger('timeout', 5);
-		$this->retries = $config->getInteger('retries', 3);
-		$this->usernameAttribute = $config->getString('username_attribute', NULL);
-		$this->nasIdentifier = $config->getString('nas_identifier',
-												  isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost');
-
-		$this->vendor = $config->getInteger('attribute_vendor', NULL);
-		if ($this->vendor !== NULL) {
-			$this->vendorType = $config->getInteger('attribute_vendor_type');
-		}
-	}
-
-
-	/**
-	 * Attempt to log in using the given username and password.
-	 *
-	 * @param string $username  The username the user wrote.
-	 * @param string $password  The password the user wrote.
-	 * @return array  Associative array with the users attributes.
-	 */
-	protected function login($username, $password) {
-		assert('is_string($username)');
-		assert('is_string($password)');
-
-		$radius = radius_auth_open();
-
-		/* Try to add all radius servers, trigger a failure if no one works. */
-		$success = false;
-		foreach ($this->servers as $server) {
-			if (!isset($server['port'])) {
-				$server['port'] = 1812;
-			}
-			if (!radius_add_server($radius, $server['hostname'], $server['port'], $server['secret'], 
-								   $this->timeout, $this->retries)) {
-				SimpleSAML_Logger::info("Could not connect to server: ".radius_strerror($radius));
-				continue;
-			}
-			$success = true;
-		}
-		if (!$success) {
-			throw new Exception('Error connecting to radius server, no servers available');
-		}
-
-		if (!radius_create_request($radius, RADIUS_ACCESS_REQUEST)) {
-			throw new Exception('Error creating radius request: ' . radius_strerror($radius));
-		}
-
-		radius_put_attr($radius, RADIUS_USER_NAME, $username);
-		radius_put_attr($radius, RADIUS_USER_PASSWORD, $password);
-
-		if ($this->nasIdentifier != NULL)
-			radius_put_attr($radius, RADIUS_NAS_IDENTIFIER, $this->nasIdentifier);
-
-		$res = radius_send_request($radius);
-		if ($res != RADIUS_ACCESS_ACCEPT) {
-			switch ($res) {
-			case RADIUS_ACCESS_REJECT:
-				/* Invalid username or password. */
-				throw new SimpleSAML_Error_Error('WRONGUSERPASS');
-			case RADIUS_ACCESS_CHALLENGE:
-				throw new Exception('Radius authentication error: Challenge requested, but not supported.');
-			default:
-				throw new Exception('Error during radius authentication: ' . radius_strerror($radius));
-			}
-		}
-
-		/* If we get this far, we have a valid login. */
-
-		$attributes = array();
-
-		if ($this->usernameAttribute !== NULL) {
-			$attributes[$this->usernameAttribute] = array($username);
-		}
-
-		if ($this->vendor === NULL) {
-			/*
-			 * We aren't interested in any vendor-specific attributes. We are
-			 * therefore done now.
-			 */
-			return $attributes;
-		}
-
-		/* get AAI attribute sets. Contributed by Stefan Winter, (c) RESTENA */
-		while ($resa = radius_get_attr($radius)) {
-
-			if (!is_array($resa)) {
-				throw new Exception('Error getting radius attributes: ' . radius_strerror($radius));
-			}
-
-			/* Use the received user name */
-			if ($resa['attr'] == RADIUS_USER_NAME) {
-				$attributes[$this->usernameAttribute] = array($resa['data']);
-				continue;
-			}
-
-			if ($resa['attr'] !== RADIUS_VENDOR_SPECIFIC) {
-				continue;
-			}
-
-			$resv = radius_get_vendor_attr($resa['data']);
-			if (!is_array($resv)) {
-				throw new Exception('Error getting vendor specific attribute: ' . radius_strerror($radius));
-			}
-
-			$vendor = $resv['vendor'];
-			$attrv = $resv['attr'];
-			$datav = $resv['data'];
-
-			if ($vendor != $this->vendor || $attrv != $this->vendorType) {
-				continue;
-			}
-
-			$attrib_name = strtok($datav,'=');
-			$attrib_value = strtok('=');
-
-			/* if the attribute name is already in result set, add another value */
-			if (array_key_exists($attrib_name, $attributes)) {
-				$attributes[$attrib_name][] = $attrib_value;
-			} else {
-				$attributes[$attrib_name] = array($attrib_value);
-			}
-		}
-		/* end of contribution */
-
-		return $attributes;
-	}
-
+class sspmod_radius_Auth_Source_Radius extends sspmod_core_Auth_UserPassBase
+{
+    /**
+     * The list of radius servers to use.
+     */
+    private $servers;
+
+    /**
+     * The hostname of the radius server.
+     */
+    private $hostname;
+
+    /**
+     * The port of the radius server.
+     */
+    private $port;
+
+    /**
+     * The secret used when communicating with the radius server.
+     */
+    private $secret;
+
+    /**
+     * The timeout for contacting the radius server.
+     */
+    private $timeout;
+
+    /**
+     * The number of retries which should be attempted.
+     */
+    private $retries;
+
+    /**
+     * The realm to be added to the entered username.
+     */
+    private $realm;
+
+    /**
+     * The attribute name where the username should be stored.
+     */
+    private $usernameAttribute;
+
+    /**
+     * The vendor for the RADIUS attributes we are interrested in.
+     */
+    private $vendor;
+
+    /**
+     * The vendor-specific attribute for the RADIUS attributes we are
+     * interrested in.
+     */
+    private $vendorType;
+
+    /**
+     * The NAS-Identifier that should be set in Access-Request packets.
+     */
+    private $nasIdentifier;
+
+    /**
+     * Constructor for this authentication source.
+     *
+     * @param array $info  Information about this authentication source.
+     * @param array $config  Configuration.
+     */
+    public function __construct($info, $config)
+    {
+        assert('is_array($info)');
+        assert('is_array($config)');
+
+        // Call the parent constructor first, as required by the interface
+        parent::__construct($info, $config);
+
+        // Parse configuration.
+        $config = SimpleSAML_Configuration::loadFromArray($config,
+            'Authentication source ' . var_export($this->authId, true));
+
+        $this->servers = $config->getArray('servers', array());
+        /* For backwards compatibility. */
+        if (empty($this->servers)) {
+            $this->hostname = $config->getString('hostname');
+            $this->port = $config->getIntegerRange('port', 1, 65535, 1812);
+            $this->secret = $config->getString('secret');
+            $this->servers[] = array('hostname' => $this->hostname,
+                                     'port' => $this->port,
+                                     'secret' => $this->secret);
+        }
+        $this->timeout = $config->getInteger('timeout', 5);
+        $this->retries = $config->getInteger('retries', 3);
+        $this->realm = $config->getString('realm', null);
+        $this->usernameAttribute = $config->getString('username_attribute', null);
+        $this->nasIdentifier = $config->getString('nas_identifier',
+            isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost');
+
+        $this->vendor = $config->getInteger('attribute_vendor', null);
+        if ($this->vendor !== null) {
+            $this->vendorType = $config->getInteger('attribute_vendor_type');
+        }
+    }
+
+
+    /**
+     * Attempt to log in using the given username and password.
+     *
+     * @param string $username  The username the user wrote.
+     * @param string $password  The password the user wrote.
+     * @return array  Associative array with the user's attributes.
+     */
+    protected function login($username, $password)
+    {
+        assert('is_string($username)');
+        assert('is_string($password)');
+
+        $radius = radius_auth_open();
+
+        /* Try to add all radius servers, trigger a failure if no one works. */
+        $success = false;
+        foreach ($this->servers as $server) {
+            if (!isset($server['port'])) {
+                $server['port'] = 1812;
+            }
+            if (!radius_add_server($radius,
+                $server['hostname'], $server['port'], $server['secret'], 
+                $this->timeout, $this->retries)) {
+                SimpleSAML_Logger::info("Could not add radius server: " .
+                    radius_strerror($radius));
+                continue;
+            }
+            $success = true;
+        }
+        if (!$success) {
+            throw new Exception('Error adding radius servers, no servers available');
+        }
+
+        if (!radius_create_request($radius, RADIUS_ACCESS_REQUEST)) {
+            throw new Exception('Error creating radius request: ' .
+                radius_strerror($radius));
+        }
+
+        if ($this->realm === null) {
+            radius_put_attr($radius, RADIUS_USER_NAME, $username);
+        } else {
+            radius_put_attr($radius, RADIUS_USER_NAME, $username . '@' . $this->realm);
+        }
+        radius_put_attr($radius, RADIUS_USER_PASSWORD, $password);
+
+        if ($this->nasIdentifier !== null) {
+            radius_put_attr($radius, RADIUS_NAS_IDENTIFIER, $this->nasIdentifier);
+        }
+
+        $res = radius_send_request($radius);
+        if ($res != RADIUS_ACCESS_ACCEPT) {
+            switch ($res) {
+            case RADIUS_ACCESS_REJECT:
+                /* Invalid username or password. */
+                throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+            case RADIUS_ACCESS_CHALLENGE:
+                throw new Exception('Radius authentication error: Challenge requested, but not supported.');
+            default:
+                throw new Exception('Error during radius authentication: ' .
+                    radius_strerror($radius));
+            }
+        }
+
+        /* If we get this far, we have a valid login. */
+
+        $attributes = array();
+
+        if ($this->usernameAttribute !== null) {
+            $attributes[$this->usernameAttribute] = array($username);
+        }
+
+        if ($this->vendor === null) {
+            /*
+             * We aren't interested in any vendor-specific attributes. We are
+             * therefore done now.
+             */
+            return $attributes;
+        }
+
+        /* get AAI attribute sets. Contributed by Stefan Winter, (c) RESTENA */
+        while ($resa = radius_get_attr($radius)) {
+
+            if (!is_array($resa)) {
+                throw new Exception('Error getting radius attributes: ' .
+                    radius_strerror($radius));
+            }
+
+            /* Use the received user name */
+            if ($resa['attr'] == RADIUS_USER_NAME) {
+                $attributes[$this->usernameAttribute] = array($resa['data']);
+                continue;
+            }
+
+            if ($resa['attr'] !== RADIUS_VENDOR_SPECIFIC) {
+                continue;
+            }
+
+            $resv = radius_get_vendor_attr($resa['data']);
+            if (!is_array($resv)) {
+                throw new Exception('Error getting vendor specific attribute: ' .
+                    radius_strerror($radius));
+            }
+
+            $vendor = $resv['vendor'];
+            $attrv = $resv['attr'];
+            $datav = $resv['data'];
+
+            if ($vendor != $this->vendor || $attrv != $this->vendorType) {
+                continue;
+            }
+
+            $attrib_name = strtok($datav,'=');
+            $attrib_value = strtok('=');
+
+            /* if the attribute name is already in result set,
+                add another value */
+            if (array_key_exists($attrib_name, $attributes)) {
+                $attributes[$attrib_name][] = $attrib_value;
+            } else {
+                $attributes[$attrib_name] = array($attrib_value);
+            }
+        }
+        /* end of contribution */
+
+        return $attributes;
+    }
 }