diff --git a/contrib/openldap/core-fd.schema b/contrib/openldap/core-fd.schema
index 2679eae8ac089308d3c83c5ae56cf18bb2fac0bb..79cf932cd47ea5d1eb542cd292f1d8a72100acab 100644
--- a/contrib/openldap/core-fd.schema
+++ b/contrib/openldap/core-fd.schema
@@ -7,12 +7,14 @@
 
 attributetype ( 1.3.6.1.4.1.10098.1.1.12.2 NAME 'gosaUser'
   DESC 'GOsa - DN of a user'
+  OBSOLETE
   EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
 
 attributetype ( 1.3.6.1.4.1.10098.1.1.12.3 NAME 'gosaObject'
   DESC 'GOsa - DN of an object'
+  OBSOLETE
   EQUALITY caseIgnoreMatch
   SUBSTR caseIgnoreSubstringsMatch
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
@@ -51,10 +53,29 @@ attributetype ( 1.3.6.1.4.1.10098.1.1.12.39 NAME 'gosaSnapshotData'
   DESC 'GOsa - Original data of saved object in snapshot'
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE)
 
+attributetype ( 1.3.6.1.4.1.38414.62.1.1 NAME 'fdUserDn'
+  DESC 'GOsa - DN of a user'
+  EQUALITY caseIgnoreMatch
+  SUBSTR caseIgnoreSubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.38414.62.1.2 NAME 'fdObjectDn'
+  DESC 'GOsa - DN of an object'
+  EQUALITY caseIgnoreMatch
+  SUBSTR caseIgnoreSubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.38414.62.1.3 NAME 'fdLockTimestamp'
+  DESC 'FusionDirectory - Lock token timestamp'
+  EQUALITY generalizedTimeMatch
+  ORDERING generalizedTimeOrderingMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )
+
 # Classes
 
 objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.2 NAME 'gosaLockEntry' SUP top STRUCTURAL
   DESC 'GOsa - Class for GOsa locking'
+  OBSOLETE
   MUST ( gosaUser $ gosaObject $ cn ))
 
 objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.4 NAME 'gosaDepartment' SUP top AUXILIARY
@@ -89,3 +110,7 @@ objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.19 NAME 'gosaSnapshotObject'
   MUST ( gosaSnapshotTimestamp $ gosaSnapshotDN $ gosaSnapshotData )
   MAY  ( description ) )
 
+objectclass ( 1.3.6.1.4.1.38414.62.2.1 NAME 'fdLockEntry' SUP top STRUCTURAL
+  DESC 'GOsa - Class for FD locking'
+  MUST ( fdUserDn $ fdObjectDn $ cn $ fdLockTimestamp ))
+
diff --git a/ihtml/themes/breezy/islocked.tpl b/ihtml/themes/breezy/islocked.tpl
index 2ce28a31ad5fb25049dd1486050a2ce7d4d46639..bc962165e22a615d2bebbcd3d5d9e63ec600c16c 100644
--- a/ihtml/themes/breezy/islocked.tpl
+++ b/ihtml/themes/breezy/islocked.tpl
@@ -9,7 +9,7 @@
       <b>{t}Warning{/t}:</b> {$message}
       <ul>
         {foreach from=$locks item=lock}
-          <li>{t 1=$lock.object 2=$lock.user}"%1" was locked by "%1"{/t}</li>
+          <li>{t 1=$lock.object 2=$lock.user 3=$lock.timestamp.format('Y-m-d, H:i:s')}"%1" was locked by "%2" since %3{/t}</li>
         {/foreach}
       </ul>
     </p>
diff --git a/include/functions.inc b/include/functions.inc
index a6dffb2e4bd63747f537903baf1cac0a210036c5..b905a7559a1c2ddd831396128c7178b4f9eafb1d 100644
--- a/include/functions.inc
+++ b/include/functions.inc
@@ -651,8 +651,8 @@ function add_lock($object, $user)
   /* Check for existing entries in lock area */
   $ldap = $config->get_ldap_link();
   $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
-  $ldap->search('(&(objectClass=gosaLockEntry)(gosaUser='.ldap_escape_f($user).')(gosaObject='.base64_encode($object).'))',
-      array('gosaUser'));
+  $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($user).')(fdObjectDn='.base64_encode($object).'))',
+      array('fdUserDn'));
   if (!$ldap->success()) {
     msg_dialog::display(_('Configuration error'), sprintf(_('Cannot create locking information in LDAP tree. Please contact your administrator!').'<br><br>'._('LDAP server returned: %s'), '<br><br><i>'.$ldap->get_error().'</i>'), ERROR_DIALOG);
     return;
@@ -662,11 +662,14 @@ function add_lock($object, $user)
   if ($ldap->count() == 0) {
     $attrs  = array();
     $name   = md5($object);
-    $ldap->cd("cn=$name,".get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
-    $attrs['objectClass'] = 'gosaLockEntry';
-    $attrs['gosaUser']    = $user;
-    $attrs['gosaObject']  = base64_encode($object);
-    $attrs['cn']          = '$name';
+    $ldap->cd('cn='.$name.','.get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
+    $attrs = array(
+      'objectClass'     => 'fdLockEntry',
+      'fdUserDn'        => $user,
+      'fdObjectDn'      => base64_encode($object),
+      'cn'              => $name,
+      'fdLockTimestamp' => LdapGeneralizedTime::toString(new DateTime('now')),
+    );
     $ldap->add($attrs);
     if (!$ldap->success()) {
       msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), "cn=$name,".get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE'], 0), LDAP_ERROR);
@@ -713,7 +716,7 @@ function del_lock ($object)
   /* Check for existance and remove the entry */
   $ldap = $config->get_ldap_link();
   $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
-  $ldap->search('(&(objectClass=gosaLockEntry)(gosaObject='.base64_encode($object).'))', array('gosaObject'));
+  $ldap->search('(&(objectClass=fdLockEntry)(fdObjectDn='.base64_encode($object).'))', array('fdObjectDn'));
   $ldap->fetch();
   if (!$ldap->success()) {
     msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), $ldap->getDN(), LDAP_DEL, ERROR_DIALOG));
@@ -741,7 +744,7 @@ function del_user_locks($userdn)
   $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
 
   /* Remove all objects of this user, drop errors silently in this case. */
-  $ldap->search('(&(objectClass=gosaLockEntry)(gosaUser='.ldap_escape_f($userdn).'))', array('gosaUser'));
+  $ldap->search('(&(objectClass=fdLockEntry)(fdUserDn='.ldap_escape_f($userdn).'))', array('fdUserDn'));
   while ($attrs = $ldap->fetch()) {
     $ldap->rmdir($attrs['dn']);
   }
@@ -802,19 +805,19 @@ function get_locks($objects)
     $objects = reset($objects);
   }
   if (is_array($objects)) {
-    $filter = '(&(objectClass=gosaLockEntry)(|';
+    $filter = '(&(objectClass=fdLockEntry)(|';
     foreach ($objects as $obj) {
-      $filter .= '(gosaObject='.base64_encode($obj).')';
+      $filter .= '(fdObjectDn='.base64_encode($obj).')';
     }
     $filter .= '))';
   } else {
-    $filter = '(&(objectClass=gosaLockEntry)(gosaObject='.base64_encode($objects).'))';
+    $filter = '(&(objectClass=fdLockEntry)(fdObjectDn='.base64_encode($objects).'))';
   }
 
   /* Get LDAP link, check for presence of the lock entry */
   $ldap = $config->get_ldap_link();
   $ldap->cd(get_ou('lockRDN').get_ou('fusiondirectoryRDN').$config->current['BASE']);
-  $ldap->search($filter, array('gosaUser','gosaObject'));
+  $ldap->search($filter, array('fdUserDn','fdObjectDn'));
   if (!$ldap->success()) {
     msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), '', LDAP_SEARCH), LDAP_ERROR);
     return FALSE;
@@ -823,9 +826,10 @@ function get_locks($objects)
   $locks = array();
   while ($attrs = $ldap->fetch()) {
     $locks[] = array(
-      'object'  => base64_decode($attrs['gosaObject'][0]),
-      'user'    => $attrs['gosaUser'][0],
-      'dn'      => $attrs['dn']
+      'dn'        => $attrs['dn'],
+      'object'    => base64_decode($attrs['fdObjectDn'][0]),
+      'user'      => $attrs['fdUserDn'][0],
+      'timestamp' => LdapGeneralizedTime::fromString($attrs['fdLockTimestamp'][0]),
     );
   }
 
@@ -2476,7 +2480,7 @@ function check_schema($cfg)
   /* core-fd */
   $checks['core-fd'] = $def_check;
   $checks['core-fd']['SCHEMA_FILE']       = 'core-fd.schema';
-  $checks['core-fd']['CLASSES_REQUIRED']  = array('gosaLockEntry');
+  $checks['core-fd']['CLASSES_REQUIRED']  = array('fdLockEntry');
   $checks['core-fd']['IS_MUST_HAVE']      = TRUE;
   $checks['core-fd']['INFO']              = _('Main FusionDirectory schema');