diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index 44162e32d47044e598e1f4d537db5c853c369417..12c6f8118d35ec0c6cbc03796a0fa6588de2f724 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -1316,32 +1316,38 @@ class Access extends LDAPUtility implements user\IUserTools {
 	 * converts a binary SID into a string representation
 	 * @param string $sid
 	 * @return string
-	 * @link http://blogs.freebsdish.org/tmclaugh/2010/07/21/finding-a-users-primary-group-in-ad/#comment-2855
 	 */
 	public function convertSID2Str($sid) {
-		try {
-			if(!function_exists('bcadd')) {
-				\OCP\Util::writeLog('user_ldap',
-					'You need to install bcmath module for PHP to have support ' .
-					'for AD primary groups', \OCP\Util::WARN);
-				throw new \Exception('missing bcmath module');
-			}
-			$srl = ord($sid[0]);
-			$numberSubID = ord($sid[1]);
-			$x = substr($sid, 2, 6);
-			$h = unpack('N', "\x0\x0" . substr($x,0,2));
-			$l = unpack('N', substr($x,2,6));
-			$iav = bcadd(bcmul($h[1], bcpow(2,32)), $l[1]);
-			$subIDs = array();
-			for ($i=0; $i<$numberSubID; $i++) {
-				$subID = unpack('V', substr($sid, 8+4*$i, 4));
-				$subIDs[] = $subID[1];
-			}
-		} catch (\Exception $e) {
+		// The format of a SID binary string is as follows:
+		// 1 byte for the revision level
+		// 1 byte for the number n of variable sub-ids
+		// 6 bytes for identifier authority value
+		// n*4 bytes for n sub-ids
+		//
+		// Example: 010400000000000515000000a681e50e4d6c6c2bca32055f
+		//  Legend: RRNNAAAAAAAAAAAA11111111222222223333333344444444
+		$revision = ord($sid[0]);
+		$numberSubID = ord($sid[1]);
+
+		$subIdStart = 8; // 1 + 1 + 6
+		$subIdLength = 4;
+		if (strlen($sid) !== $subIdStart + $subIdLength * $numberSubID) {
+			// Incorrect number of bytes present.
 			return '';
 		}
 
-		return sprintf('S-%d-%d-%s', $srl, $iav, implode('-', $subIDs));
+		// 6 bytes = 48 bits can be represented using floats without loss of
+		// precision (see https://gist.github.com/bantu/886ac680b0aef5812f71)
+		$iav = number_format(hexdec(bin2hex(substr($sid, 2, 6))), 0, '', '');
+
+		$subIDs = array();
+		for ($i = 0; $i < $numberSubID; $i++) {
+			$subID = unpack('V', substr($sid, $subIdStart + $subIdLength * $i, $subIdLength));
+			$subIDs[] = sprintf('%u', $subID[1]);
+		}
+
+		// Result for example above: S-1-5-21-249921958-728525901-1594176202
+		return sprintf('S-%d-%s-%s', $revision, $iav, implode('-', $subIDs));
 	}
 
 	/**
diff --git a/apps/user_ldap/tests/access.php b/apps/user_ldap/tests/access.php
index f436784675dcff53bb71cc23f1366efdea327590..8ff39800808171978f950f93dd6398c82c930310 100644
--- a/apps/user_ldap/tests/access.php
+++ b/apps/user_ldap/tests/access.php
@@ -78,55 +78,52 @@ class Test_Access extends \PHPUnit_Framework_TestCase {
 		$this->assertTrue($expected === $access->escapeFilterPart($input));
 	}
 
-	public function testConvertSID2StrSuccess() {
+	/** @dataProvider convertSID2StrSuccessData */
+	public function testConvertSID2StrSuccess(array $sidArray, $sidExpected) {
 		list($lw, $con, $um) = $this->getConnecterAndLdapMock();
 		$access = new Access($con, $lw, $um);
 
-		if(!function_exists('\bcadd')) {
-			$this->markTestSkipped('bcmath not available');
-		}
-
-		$sidBinary = file_get_contents(__DIR__ . '/data/sid.dat');
-		$sidExpected = 'S-1-5-21-249921958-728525901-1594176202';
-
+		$sidBinary = implode('', $sidArray);
 		$this->assertSame($sidExpected, $access->convertSID2Str($sidBinary));
 	}
 
+	public function convertSID2StrSuccessData() {
+		return array(
+			array(
+				array(
+					"\x01",
+					"\x04",
+					"\x00\x00\x00\x00\x00\x05",
+					"\x15\x00\x00\x00",
+					"\xa6\x81\xe5\x0e",
+					"\x4d\x6c\x6c\x2b",
+					"\xca\x32\x05\x5f",
+				),
+				'S-1-5-21-249921958-728525901-1594176202',
+			),
+			array(
+				array(
+					"\x01",
+					"\x02",
+					"\xFF\xFF\xFF\xFF\xFF\xFF",
+					"\xFF\xFF\xFF\xFF",
+					"\xFF\xFF\xFF\xFF",
+				),
+				'S-1-281474976710655-4294967295-4294967295',
+			),
+		);
+	}
+
 	public function testConvertSID2StrInputError() {
 		list($lw, $con, $um) = $this->getConnecterAndLdapMock();
 		$access = new Access($con, $lw, $um);
 
-		if(!function_exists('\bcadd')) {
-			$this->markTestSkipped('bcmath not available');
-		}
-
 		$sidIllegal = 'foobar';
 		$sidExpected = '';
 
 		$this->assertSame($sidExpected, $access->convertSID2Str($sidIllegal));
 	}
 
-	public function testConvertSID2StrNoBCMath() {
-		if(function_exists('\bcadd')) {
-			$removed = false;
-			if(function_exists('runkit_function_remove')) {
-				$removed = !runkit_function_remove('\bcadd');
-			}
-			if(!$removed) {
-				$this->markTestSkipped('bcadd could not be removed for ' .
-					'testing without bcmath');
-			}
-		}
-
-		list($lw, $con, $um) = $this->getConnecterAndLdapMock();
-		$access = new Access($con, $lw, $um);
-
-		$sidBinary = file_get_contents(__DIR__ . '/data/sid.dat');
-		$sidExpected = '';
-
-		$this->assertSame($sidExpected, $access->convertSID2Str($sidBinary));
-	}
-
 	public function testGetDomainDNFromDNSuccess() {
 		list($lw, $con, $um) = $this->getConnecterAndLdapMock();
 		$access = new Access($con, $lw, $um);
diff --git a/apps/user_ldap/tests/data/sid.dat b/apps/user_ldap/tests/data/sid.dat
deleted file mode 100644
index 3d500c6a872f3c8904df6fe85af623dbce42b0b2..0000000000000000000000000000000000000000
Binary files a/apps/user_ldap/tests/data/sid.dat and /dev/null differ