diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index ecc74b6cf54a585ab36876a29605933823f491f6..72f9c740921233e84820b3e35cce8860f7da093b 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -634,6 +634,10 @@ class Access extends LDAPUtility {
 		return $this->search($filter, $this->connection->ldapBaseUsers, $attr, $limit, $offset);
 	}
 
+	public function countUsers($filter, $attr = array('dn'), $limit = null, $offset = null) {
+		return $this->count($filter, $this->connection->ldapBaseGroups, $attr, $limit, $offset);
+	}
+
 	/**
 	 * @brief executes an LDAP search, optimized for Groups
 	 * @param $filter the LDAP filter for the search
@@ -647,61 +651,68 @@ class Access extends LDAPUtility {
 	}
 
 	/**
-	 * @brief executes an LDAP search
+	 * @brief prepares and executes an LDAP search operation
 	 * @param $filter the LDAP filter for the search
 	 * @param $base an array containing the LDAP subtree(s) that shall be searched
 	 * @param $attr optional, array, one or more attributes that shall be
 	 * retrieved. Results will according to the order in the array.
-	 * @returns array with the search result
-	 *
-	 * Executes an LDAP search
+	 * @param $limit optional, maximum results to be counted
+	 * @param $offset optional, a starting point
+	 * @returns array with the search result as first value and pagedSearchOK as
+	 * second | false if not successful
 	 */
-	private function search($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) {
+	private function executeSearch($filter, $base, &$attr = null, $limit = null, $offset = null) {
 		if(!is_null($attr) && !is_array($attr)) {
 			$attr = array(mb_strtolower($attr, 'UTF-8'));
 		}
 
 		// See if we have a resource, in case not cancel with message
-		$link_resource = $this->connection->getConnectionResource();
-		if(!$this->ldap->isResource($link_resource)) {
+		$cr = $this->connection->getConnectionResource();
+		if(!$this->ldap->isResource($cr)) {
 			// Seems like we didn't find any resource.
 			// Return an empty array just like before.
 			\OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG);
-			return array();
+			return false;
 		}
 
 		//check wether paged search should be attempted
 		$pagedSearchOK = $this->initPagedSearch($filter, $base, $attr, $limit, $offset);
 
-		$linkResources = array_pad(array(), count($base), $link_resource);
+		$linkResources = array_pad(array(), count($base), $cr);
 		$sr = $this->ldap->search($linkResources, $base, $filter, $attr);
-		$error = $this->ldap->errno($link_resource);
+		$error = $this->ldap->errno($cr);
 		if(!is_array($sr) || $error !== 0) {
 			\OCP\Util::writeLog('user_ldap',
-				'Error when searching: '.$this->ldap->error($link_resource).
-					' code '.$this->ldap->errno($link_resource),
+				'Error when searching: '.$this->ldap->error($cr).
+					' code '.$this->ldap->errno($cr),
 				\OCP\Util::ERROR);
 			\OCP\Util::writeLog('user_ldap', 'Attempt for Paging?  '.print_r($pagedSearchOK, true), \OCP\Util::ERROR);
-			return array();
+			return false;
 		}
 
-		// Do the server-side sorting
-		foreach(array_reverse($attr) as $sortAttr){
-			foreach($sr as $searchResource) {
-				$this->ldap->sort($link_resource, $searchResource, $sortAttr);
-			}
-		}
+		return array($sr, $pagedSearchOK);
+	}
 
-		$findings = array();
-		foreach($sr as $key => $res) {
-		    $findings = array_merge($findings, $this->ldap->getEntries($link_resource, $res ));
-		}
+	/**
+	 * @brief processes an LDAP paged search operation
+	 * @param $sr the array containing the LDAP search resources
+	 * @param $filter the LDAP filter for the search
+	 * @param $base an array containing the LDAP subtree(s) that shall be searched
+	 * @param $iFoundItems number of results in the search operation
+	 * @param $limit maximum results to be counted
+	 * @param $offset a starting point
+	 * @param $pagedSearchOK whether a paged search has been executed
+	 * @param $skipHandling required for paged search when cookies to
+	 * prior results need to be gained
+	 * @returns array with the search result as first value and pagedSearchOK as
+	 * second | false if not successful
+	 */
+	private function processPagedSearchStatus($sr, $filter, $base, $iFoundItems, $limit, $offset, $pagedSearchOK, $skipHandling) {
 		if($pagedSearchOK) {
-			\OCP\Util::writeLog('user_ldap', 'Paged search successful', \OCP\Util::INFO);
+			$cr = $this->connection->getConnectionResource();
 			foreach($sr as $key => $res) {
 				$cookie = null;
-				if($this->ldap->controlPagedResultResponse($link_resource, $res, $cookie)) {
-					\OCP\Util::writeLog('user_ldap', 'Set paged search cookie', \OCP\Util::INFO);
+				if($this->ldap->controlPagedResultResponse($cr, $res, $cookie)) {
 					$this->setPagedResultCookie($base[$key], $filter, $limit, $offset, $cookie);
 				}
 			}
@@ -713,7 +724,7 @@ class Access extends LDAPUtility {
 			// if count is bigger, then the server does not support
 			// paged search. Instead, he did a normal search. We set a
 			// flag here, so the callee knows how to deal with it.
-			if($findings['count'] <= $limit) {
+			if($iFoundItems <= $limit) {
 				$this->pagedSearchedSuccessful = true;
 			}
 		} else {
@@ -721,6 +732,86 @@ class Access extends LDAPUtility {
 				\OCP\Util::writeLog('user_ldap', 'Paged search failed :(', \OCP\Util::INFO);
 			}
 		}
+	}
+
+	/**
+	 * @brief executes an LDAP search, but counts the results only
+	 * @param $filter the LDAP filter for the search
+	 * @param $base an array containing the LDAP subtree(s) that shall be searched
+	 * @param $attr optional, array, one or more attributes that shall be
+	 * retrieved. Results will according to the order in the array.
+	 * @param $limit optional, maximum results to be counted
+	 * @param $offset optional, a starting point
+	 * @param $skipHandling indicates whether the pages search operation is
+	 * completed
+	 * @returns int | false if the search could not be initialized
+	 *
+	 */
+	private function count($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) {
+		\OCP\Util::writeLog('user_ldap', 'Count filter:  '.print_r($filter, true), \OCP\Util::DEBUG);
+		$search = $this->executeSearch($filter, $base, $attr, $limit, $offset);
+		if($search === false) {
+			return false;
+		}
+		list($sr, $pagedSearchOK) = $search;
+		$cr = $this->connection->getConnectionResource();
+		$counter = 0;
+		foreach($sr as $key => $res) {
+			$count = $this->ldap->countEntries($cr, $res);
+		    if($count !== false) {
+				$counter += $count;
+			}
+		}
+
+		$this->processPagedSearchStatus($sr, $filter, $base, $counter, $limit,
+										$offset, $pagedSearchOK, $skipHandling);
+
+		return $counter;
+	}
+
+	/**
+	 * @brief executes an LDAP search
+	 * @param $filter the LDAP filter for the search
+	 * @param $base an array containing the LDAP subtree(s) that shall be searched
+	 * @param $attr optional, array, one or more attributes that shall be
+	 * retrieved. Results will according to the order in the array.
+	 * @returns array with the search result
+	 *
+	 * Executes an LDAP search
+	 */
+	private function search($filter, $base, $attr = null, $limit = null, $offset = null, $skipHandling = false) {
+		$search = $this->executeSearch($filter, $base, $attr, $limit, $offset);
+		if($search === false) {
+			return array();
+		}
+		list($sr, $pagedSearchOK) = $search;
+		$cr = $this->connection->getConnectionResource();
+
+		if($skipHandling) {
+			//i.e. result do not need to be fetched, we just need the cookie
+			//thus pass 1 or any other value as $iFoundItems because it is not
+			//used
+			$this->processPagedSearchStatus($sr, $filter, $base, 1, $limit,
+											$offset, $pagedSearchOK,
+											$skipHandling);
+			return;
+		}
+
+		// Do the server-side sorting
+		foreach(array_reverse($attr) as $sortAttr){
+			foreach($sr as $searchResource) {
+				$this->ldap->sort($cr, $searchResource, $sortAttr);
+			}
+		}
+
+		$findings = array();
+		foreach($sr as $key => $res) {
+		    $findings = array_merge($findings, $this->ldap->getEntries($cr	, $res ));
+		}
+
+		$this->processPagedSearchStatus($sr, $filter, $base, $findings['count'],
+										$limit, $offset, $pagedSearchOK,
+										$skipHandling);
 
 		// if we're here, probably no connection resource is returned.
 		// to make ownCloud behave nicely, we simply give back an empty array.
diff --git a/apps/user_ldap/tests/user_ldap.php b/apps/user_ldap/tests/user_ldap.php
index 6b9b8b3e18503162fcfc90638c5b09250df6b126..9193a005ae5da9aa9d0861e1d085282756d02858 100644
--- a/apps/user_ldap/tests/user_ldap.php
+++ b/apps/user_ldap/tests/user_ldap.php
@@ -408,4 +408,58 @@ class Test_User_Ldap_Direct extends \PHPUnit_Framework_TestCase {
 
 	//no test for getDisplayNames, because it just invokes getUsers and
 	//getDisplayName
+
+	public function testCountUsers() {
+		$access = $this->getAccessMock();
+
+		$access->connection->expects($this->once())
+			   ->method('__get')
+			   ->will($this->returnCallback(function($name) {
+					if($name === 'ldapLoginFilter') {
+						return 'uid=%uid';
+					}
+					return null;
+			   }));
+
+		$access->expects($this->once())
+			   ->method('countUsers')
+			   ->will($this->returnCallback(function($filter, $a, $b, $c) {
+				   if($filter !== 'uid=*') {
+					   return false;
+				   }
+				   return 5;
+			   }));
+
+		$backend = new UserLDAP($access);
+
+		$result = $backend->countUsers();
+		$this->assertEquals(5, $result);
+	}
+
+	public function testCountUsersFailing() {
+		$access = $this->getAccessMock();
+
+		$access->connection->expects($this->once())
+			   ->method('__get')
+			   ->will($this->returnCallback(function($name) {
+					if($name === 'ldapLoginFilter') {
+						return 'invalidFilter';
+					}
+					return null;
+			   }));
+
+		$access->expects($this->once())
+			   ->method('countUsers')
+			   ->will($this->returnCallback(function($filter, $a, $b, $c) {
+				   if($filter !== 'uid=*') {
+					   return false;
+				   }
+				   return 5;
+			   }));
+
+		$backend = new UserLDAP($access);
+
+		$result = $backend->countUsers();
+		$this->assertFalse($result);
+	}
 }
\ No newline at end of file
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index 527a5c10b85885f3bbe3969222c19efb014f28b2..a19af86086c91d7b5dc76ab29aa953806835270f 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -363,7 +363,8 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
 		return (bool)((OC_USER_BACKEND_CHECK_PASSWORD
 			| OC_USER_BACKEND_GET_HOME
 			| OC_USER_BACKEND_GET_DISPLAYNAME
-			| OC_USER_BACKEND_PROVIDE_AVATAR)
+			| OC_USER_BACKEND_PROVIDE_AVATAR
+			| OC_USER_BACKEND_COUNT_USERS)
 			& $actions);
 	}
 
@@ -373,4 +374,16 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
 	public function hasUserListings() {
 		return true;
 	}
+
+	/**
+	 * counts the users in LDAP
+	 *
+	 * @return int | bool
+	 */
+	public function countUsers() {
+		$filter = \OCP\Util::mb_str_replace(
+			'%uid', '*', $this->access->connection->ldapLoginFilter, 'UTF-8');
+		$entries = $this->access->countUsers($filter);
+		return $entries;
+	}
 }
diff --git a/apps/user_ldap/user_proxy.php b/apps/user_ldap/user_proxy.php
index b073b143e74283c323b91b7e5161f7377cf03d0b..5ad127197f311385ad8531bc497eae6fe233e9e6 100644
--- a/apps/user_ldap/user_proxy.php
+++ b/apps/user_ldap/user_proxy.php
@@ -210,4 +210,19 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface {
 		return $this->refBackend->hasUserListings();
 	}
 
+	/**
+	 * @brief Count the number of users
+	 * @returns int | bool
+	 */
+	public function countUsers() {
+		$users = false;
+		foreach($this->backends as $backend) {
+			$backendUsers = $backend->countUsers();
+			if ($backendUsers !== false) {
+				$users += $backendUsers;
+			}
+		}
+		return $users;
+	}
+
 }
diff --git a/core/command/user/report.php b/core/command/user/report.php
new file mode 100644
index 0000000000000000000000000000000000000000..f95ba251bcca158e2c38a5414b97d0a50c63f793
--- /dev/null
+++ b/core/command/user/report.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Copyright (c) 2014 Arthur Schiwon <blizzz@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Core\Command\User;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Helper\TableHelper;
+
+class Report extends Command {
+	protected function configure() {
+		$this
+			->setName('user:report')
+			->setDescription('shows how many users have access');
+	}
+
+	protected function execute(InputInterface $input, OutputInterface $output) {
+		$table = $this->getHelperSet()->get('table');
+		$table->setHeaders(array('User Report', ''));
+		$userCountArray = $this->countUsers();
+		if(!empty($userCountArray)) {
+			$total = 0;
+			$rows = array();
+			foreach($userCountArray as $classname => $users) {
+				$total += $users;
+				$rows[] = array($classname, $users);
+			}
+
+			$rows[] = array(' ');
+			$rows[] = array('total users', $total);
+		} else {
+			$rows[] = array('No backend enabled that supports user counting', '');
+		}
+
+		$userDirectoryCount = $this->countUserDirectories();
+		$rows[] = array(' ');
+		$rows[] = array('user directories', $userDirectoryCount);
+
+		$table->setRows($rows);
+		$table->render($output);
+	}
+
+	private function countUsers() {
+		\OC_App::loadApps(array('authentication'));
+		$userManager = \OC::$server->getUserManager();
+		return $userManager->countUsers();
+	}
+
+	private function countUserDirectories() {
+		$dataview = new \OC\Files\View('/');
+		$userDirectories = $dataview->getDirectoryContent('/', 'httpd/unix-directory');
+		return count($userDirectories);
+	}
+}
\ No newline at end of file
diff --git a/core/register_command.php b/core/register_command.php
index e4f3b124365b92c08321fb7fc94eed343852882d..2efa838e9ee9b8c69c1e8b3e195862d6be086a0d 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -15,3 +15,4 @@ $application->add(new OC\Core\Command\App\Disable());
 $application->add(new OC\Core\Command\App\Enable());
 $application->add(new OC\Core\Command\App\ListApps());
 $application->add(new OC\Core\Command\Maintenance\Repair(new \OC\Repair()));
+$application->add(new OC\Core\Command\User\Report());
diff --git a/lib/private/user/backend.php b/lib/private/user/backend.php
index 02c93d13bdfc13f5120a8fb1e42d816676534b9e..f4e5618e04ad11c93dff1e626596cc1fd3d900bb 100644
--- a/lib/private/user/backend.php
+++ b/lib/private/user/backend.php
@@ -31,13 +31,15 @@ define('OC_USER_BACKEND_NOT_IMPLEMENTED',   -501);
 /**
  * actions that user backends can define
  */
-define('OC_USER_BACKEND_CREATE_USER',       0x0000001);
-define('OC_USER_BACKEND_SET_PASSWORD',      0x0000010);
-define('OC_USER_BACKEND_CHECK_PASSWORD',    0x0000100);
-define('OC_USER_BACKEND_GET_HOME',			0x0001000);
-define('OC_USER_BACKEND_GET_DISPLAYNAME',	0x0010000);
-define('OC_USER_BACKEND_SET_DISPLAYNAME',	0x0100000);
-define('OC_USER_BACKEND_PROVIDE_AVATAR',	0x1000000);
+define('OC_USER_BACKEND_CREATE_USER',       0x00000001);
+define('OC_USER_BACKEND_SET_PASSWORD',      0x00000010);
+define('OC_USER_BACKEND_CHECK_PASSWORD',    0x00000100);
+define('OC_USER_BACKEND_GET_HOME',			0x00001000);
+define('OC_USER_BACKEND_GET_DISPLAYNAME',	0x00010000);
+define('OC_USER_BACKEND_SET_DISPLAYNAME',	0x00100000);
+define('OC_USER_BACKEND_PROVIDE_AVATAR',	0x01000000);
+define('OC_USER_BACKEND_COUNT_USERS',		0x10000000);
+//more actions cannot be defined without breaking 32bit platforms!
 
 /**
  * Abstract base class for user management. Provides methods for querying backend
@@ -55,6 +57,7 @@ abstract class OC_User_Backend implements OC_User_Interface {
 		OC_USER_BACKEND_GET_DISPLAYNAME => 'getDisplayName',
 		OC_USER_BACKEND_SET_DISPLAYNAME => 'setDisplayName',
 		OC_USER_BACKEND_PROVIDE_AVATAR => 'canChangeAvatar',
+		OC_USER_BACKEND_COUNT_USERS => 'countUsers',
 	);
 
 	/**
diff --git a/lib/private/user/database.php b/lib/private/user/database.php
index c99db3b27ca715f40ea6dcd0e0e57308072c4343..1a63755b980f652e7034fe85a004a0931ad6ddee 100644
--- a/lib/private/user/database.php
+++ b/lib/private/user/database.php
@@ -253,4 +253,19 @@ class OC_User_Database extends OC_User_Backend {
 		return true;
 	}
 
+	/**
+	 * counts the users in the database
+	 *
+	 * @return int | bool
+	 */
+	public function countUsers() {
+		$query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`');
+		$result = $query->execute();
+		if (OC_DB::isError($result)) {
+			OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR);
+			return false;
+		}
+		return $result->fetchOne();
+	}
+
 }
diff --git a/lib/private/user/dummy.php b/lib/private/user/dummy.php
index 52be7edfa7534433c364772831562b45ceeeae33..fc15a630cf3991b13246b73d7e6840c6c05a7551 100644
--- a/lib/private/user/dummy.php
+++ b/lib/private/user/dummy.php
@@ -123,4 +123,13 @@ class OC_User_Dummy extends OC_User_Backend {
 	public function hasUserListings() {
 		return true;
 	}
+
+	/**
+	 * counts the users in the database
+	 *
+	 * @return int | bool
+	 */
+	public function countUsers() {
+		return 0;
+	}
 }
diff --git a/lib/private/user/manager.php b/lib/private/user/manager.php
index cf83a75ba25dfd27d3be49a956deeeb928347311..90970ef996349a44254fc51b78b49f084eee12eb 100644
--- a/lib/private/user/manager.php
+++ b/lib/private/user/manager.php
@@ -270,4 +270,26 @@ class Manager extends PublicEmitter {
 		}
 		return false;
 	}
+
+	/**
+	 * returns how many users per backend exist (if supported by backend)
+	 *
+	 * @return array with backend class as key and count number as value
+	 */
+	public function countUsers() {
+		$userCountStatistics = array();
+		foreach ($this->backends as $backend) {
+			if ($backend->implementsActions(\OC_USER_BACKEND_COUNT_USERS)) {
+				$backendusers = $backend->countUsers();
+				if($backendusers !== false) {
+					if(isset($userCountStatistics[get_class($backend)])) {
+						$userCountStatistics[get_class($backend)] += $backendusers;
+					} else {
+						$userCountStatistics[get_class($backend)] = $backendusers;
+					}
+				}
+			}
+		}
+		return $userCountStatistics;
+	}
 }
diff --git a/tests/lib/user/manager.php b/tests/lib/user/manager.php
index 00901dd4115c7e83aa4af3859b71957fbfa73dfb..ad1ac9e12f2604a6201a0fb2269df177fcfacce0 100644
--- a/tests/lib/user/manager.php
+++ b/tests/lib/user/manager.php
@@ -346,4 +346,76 @@ class Manager extends \PHPUnit_Framework_TestCase {
 
 		$manager->createUser('foo', 'bar');
 	}
+
+	public function testCountUsersNoBackend() {
+		$manager = new \OC\User\Manager();
+
+		$result = $manager->countUsers();
+		$this->assertTrue(is_array($result));
+		$this->assertTrue(empty($result));
+	}
+
+	public function testCountUsersOneBackend() {
+		/**
+		 * @var \OC_User_Dummy | \PHPUnit_Framework_MockObject_MockObject $backend
+		 */
+		$backend = $this->getMock('\OC_User_Dummy');
+		$backend->expects($this->once())
+			->method('countUsers')
+			->will($this->returnValue(7));
+
+		$backend->expects($this->once())
+			->method('implementsActions')
+			->with(\OC_USER_BACKEND_COUNT_USERS)
+			->will($this->returnValue(true));
+
+		$manager = new \OC\User\Manager();
+		$manager->registerBackend($backend);
+
+		$result = $manager->countUsers();
+		$keys = array_keys($result);
+		$this->assertTrue(strpos($keys[0], 'Mock_OC_User_Dummy') !== false);
+
+		$users = array_shift($result);
+		$this->assertEquals(7, $users);
+	}
+
+	public function testCountUsersTwoBackends() {
+		/**
+		 * @var \OC_User_Dummy | \PHPUnit_Framework_MockObject_MockObject $backend
+		 */
+		$backend1 = $this->getMock('\OC_User_Dummy');
+		$backend1->expects($this->once())
+			->method('countUsers')
+			->will($this->returnValue(7));
+
+		$backend1->expects($this->once())
+			->method('implementsActions')
+			->with(\OC_USER_BACKEND_COUNT_USERS)
+			->will($this->returnValue(true));
+
+		$backend2 = $this->getMock('\OC_User_Dummy');
+		$backend2->expects($this->once())
+			->method('countUsers')
+			->will($this->returnValue(16));
+
+		$backend2->expects($this->once())
+			->method('implementsActions')
+			->with(\OC_USER_BACKEND_COUNT_USERS)
+			->will($this->returnValue(true));
+
+		$manager = new \OC\User\Manager();
+		$manager->registerBackend($backend1);
+		$manager->registerBackend($backend2);
+
+		$result = $manager->countUsers();
+		//because the backends have the same class name, only one value expected
+		$this->assertEquals(1, count($result));
+		$keys = array_keys($result);
+		$this->assertTrue(strpos($keys[0], 'Mock_OC_User_Dummy') !== false);
+
+		$users = array_shift($result);
+		//users from backends shall be summed up
+		$this->assertEquals(7+16, $users);
+	}
 }