diff --git a/include/class_SnapshotDialogs.inc b/include/class_SnapshotDialogs.inc
index 50437cc9be86c6bf60de22b8067ef976f4791300..bd2c74bb373de1b5a7276b44f393fbb424c0a637 100644
--- a/include/class_SnapshotDialogs.inc
+++ b/include/class_SnapshotDialogs.inc
@@ -205,7 +205,9 @@ class SnapshotRestoreDialog extends simplePlugin
           ),
           new SnapshotsAttribute (
             _('Snapshots'), _('Existing snapshots for this object'),
-            'snapshots', FALSE
+            'snapshots', FALSE,
+            array(),
+            'SnapshotHandler'
           ),
         )
       ),
@@ -236,6 +238,7 @@ class SnapshotRestoreDialog extends simplePlugin
 
   function execute ()
   {
+    global $ui;
     if ($this->dialog == 'delete') {
       $objects = array(
         array(
@@ -265,6 +268,19 @@ class SnapshotRestoreDialog extends simplePlugin
       $smarty->assign('objects', $objects);
       $str = $smarty->fetch(get_template_path('restore-confirm.tpl'));
     } else {
+      $smarty = get_smarty();
+      $permissions = $ui->get_snapshot_permissions($this->acl_base, $this->aclCategory);
+      $acl = '';
+      if (in_array('r', $permissions)) {
+        $acl .= 'r';
+      }
+      if (in_array(($this->global ? 'restore_deleted' : 'restore_over'), $permissions)) {
+        $acl .= 'w';
+      }
+      if (in_array('d', $permissions)) {
+        $acl .= 'd';
+      }
+      $smarty->assign('SnapshotHandlerACL', $acl);
       $str = parent::execute();
       $str .= '<p class="plugbottom">'.
              '  <input type="submit" name="edit_cancel" value="'.msgPool::backButton().'"/>'.
diff --git a/include/class_SnapshotHandler.inc b/include/class_SnapshotHandler.inc
index 234e9d03537457ccd7b8056767c8655d863ac33b..cc11cecbac62470f462455c1d3710bf87187650b 100644
--- a/include/class_SnapshotHandler.inc
+++ b/include/class_SnapshotHandler.inc
@@ -34,6 +34,21 @@ class SnapshotHandler
 
   protected $enabled;
 
+  static function plInfo()
+  {
+    return array(
+      'plShortName'   => _('Snapshot'),
+      'plDescription' => _('Snapshot handler'),
+      /* Categories for snapshots are computed in config class */
+      'plCategory'    => array(),
+
+      'plProvidedAcls' => array(
+        'restore_over'    => _('Restore over an existing object'),
+        'restore_deleted' => _('Restore a deleted object'),
+      )
+    );
+  }
+
   /*!
    * \brief Create handler
    *
diff --git a/include/class_config.inc b/include/class_config.inc
index 212a95e9423ad7b6362154f23fb94d515bb6269e..b4fe55e77483fb8cd0b083ec58a3093870468480 100644
--- a/include/class_config.inc
+++ b/include/class_config.inc
@@ -839,6 +839,7 @@ class config
             $value['tabGroup']        = $tabclass;
             $value['mainTab']         = $class;
             $value['templateActive']  = FALSE;
+            $value['snapshotActive']  = FALSE;
             foreach (array('ou', 'tabClass') as $i) {
               if (!isset($value[$i])) {
                 $value[$i] = NULL;
@@ -985,6 +986,10 @@ class config
               $this->data['OBJECTS'][$obj]['templateActive']  = TRUE;
               $this->data['CATEGORIES'][$cat]['classes'][]    = 'template';
             }
+            if (isset($class::$skipSnapshots) && ($class::$skipSnapshots == FALSE)) {
+              $this->data['OBJECTS'][$obj]['snapshotActive']  = TRUE;
+              $this->data['CATEGORIES'][$cat]['classes'][]    = 'SnapshotHandler';
+            }
           }
         }
       }
diff --git a/include/class_listing.inc b/include/class_listing.inc
index 618014341b5ca763c99a29a614219b940da93548..a37e6aeec12f0d7bb7dfd0b75fa67feb354fd156 100644
--- a/include/class_listing.inc
+++ b/include/class_listing.inc
@@ -1717,7 +1717,7 @@ class listing
     $result = "";
     $ui     = get_userinfo();
 
-    if ($ui->allow_snapshot_restore($this->base, $this->categories)) {
+    if ($ui->allow_snapshot_restore($this->base, $this->categories, TRUE)) {
       // Draw icons according to the restore flag
       if ($this->snapshotHandler->hasDeletedSnapshots()) {
         $result .= $this->renderActionMenuActionLink($separator, 'restore', _('Restore snapshots'), 'geticon.php?context=actions&icon=document-restore&size=16');
@@ -1761,7 +1761,7 @@ class listing
     $result = '';
     $ui = get_userinfo();
 
-    if ($ui->allow_snapshot_restore($dn, $category)) {
+    if ($ui->allow_snapshot_restore($dn, $category, FALSE)) {
       /* Draw restore button */
 
       if ($this->snapshotHandler->hasSnapshots($dn)) {
diff --git a/include/class_userinfo.inc b/include/class_userinfo.inc
index 4e6133e1361a3ea822697e3d7e926c2820036886..b9bcbdb29730b984b85ba8643ce726699c7c981e 100644
--- a/include/class_userinfo.inc
+++ b/include/class_userinfo.inc
@@ -353,21 +353,16 @@ class userinfo
    *
    * \param string $dn     The destination dn
    *
-   * \param string $object The acl  category (e.g. user)
+   * \param string $categories The acl  category (e.g. user)
+   *
+   * \param boolean $deleted Is it a deleted or existing object
    *
    * \return boolean TRUE if we are allowed to restore a snapshot.
    */
-  function allow_snapshot_restore($dn, $object)
+  function allow_snapshot_restore($dn, $categories, $deleted)
   {
-    if (!is_array($object)) {
-      $object = array($object);
-    }
-    $r = $w = TRUE;
-    foreach ($object as $category) {
-      $w &= (strpos($this->get_complete_category_acls($dn, $category), 'w') !== FALSE);
-      $r &= (strpos($this->get_complete_category_acls($dn, $category), 'r') !== FALSE);
-    }
-    return ($r && $w);
+    $permissions = $this->get_snapshot_permissions($dn, $categories);
+    return in_array(($deleted ? 'restore_deleted' : 'restore_over'), $permissions);
   }
 
 
@@ -376,21 +371,55 @@ class userinfo
    *
    * \param string $dn     The source dn
    *
-   * \param string $object The acl category (e.g. user)
+   * \param string $categories The acl category (e.g. user)
    *
-   * \return boolean TRUE if we are allowed to restore a snapshot.
+   * \return boolean TRUE if we are allowed to create a snapshot.
    */
-  function allow_snapshot_create($dn, $object)
+  function allow_snapshot_create($dn, $categories)
   {
-    if (!is_array($object)) {
-      $object = array($object);
+    $permissions = $this->get_snapshot_permissions($dn, $categories);
+    return in_array('c', $permissions);
+  }
+
+
+  /*!
+   * \brief Checks if we are allowed to delete a snapshot of the given dn.
+   *
+   * \param string $dn     The source dn
+   *
+   * \param string $categories The acl category (e.g. user)
+   *
+   * \return boolean TRUE if we are allowed to delete a snapshot.
+   */
+  function allow_snapshot_delete($dn, $categories)
+  {
+    $permissions = $this->get_snapshot_permissions($dn, $categories);
+    return in_array('d', $permissions);
+  }
+
+  function get_snapshot_permissions($dn, $categories)
+  {
+    if (!is_array($categories)) {
+      $categories = array($categories);
     }
-    foreach ($object as $category) {
-      if (strpos($this->get_complete_category_acls($dn, $category), 'r') === FALSE) {
-        return FALSE;
+    /* Possible permissions for snapshots */
+    $objectPermissions    = array('r', 'c', 'd');
+    $attributePermissions = array('restore_over', 'restore_deleted');
+    foreach ($categories as $category) {
+      $acl = $this->get_permissions($dn, $category.'/SnapshotHandler');
+      foreach ($objectPermissions as $i => $perm) {
+        if (strpos($acl, $perm) === FALSE) {
+          unset($objectPermissions[$i]);
+        }
+      }
+      foreach ($attributePermissions as $i => $attribute) {
+        $acl = $this->get_permissions($dn, $category.'/SnapshotHandler', $attribute);
+        if (strpos($acl, 'w') === FALSE) {
+          unset($attributePermissions[$i]);
+        }
       }
     }
-    return TRUE;
+    return array_merge($objectPermissions, $attributePermissions);
   }
 
   /*!
diff --git a/include/simpleplugin/class_simpleManagement.inc b/include/simpleplugin/class_simpleManagement.inc
index 2980c169c714dbed2aab94aaeec834ad4e374fef..c58acb661f7c801dea5a1e8bc26000372a2b6266 100644
--- a/include/simpleplugin/class_simpleManagement.inc
+++ b/include/simpleplugin/class_simpleManagement.inc
@@ -184,13 +184,13 @@ class simpleManagement
   protected $autoFilter       = TRUE;
   protected $autoActions      = TRUE;
   protected $skipCpHandler    = FALSE;
-  protected $skipSnapHandler  = FALSE;
 
   protected $autoFilterAttributes = array('dn', 'cn', 'description');
 
   protected $headpageClass = "listing";
 
   public static $skipTemplates = TRUE;
+  public static $skipSnapshots = FALSE;
 
   function __construct()
   {
@@ -247,7 +247,7 @@ class simpleManagement
       $this->registerAction('cut',    'copyPasteHandler');
       $this->registerAction('paste',  'copyPasteHandler');
     }
-    if (!$this->skipSnapHandler && ($config->get_cfg_value('enableSnapshots') == 'TRUE')) {
+    if (!self::$skipSnapshots && ($config->get_cfg_value('enableSnapshots') == 'TRUE')) {
       $this->snapHandler = new SnapshotHandler();
       $this->headpage->setSnapshotHandler($this->snapHandler);
       $this->registerAction('snapshot', 'createSnapshotDialog');
@@ -1171,10 +1171,10 @@ class simpleManagement
       if (empty($this->dn)) {
         return;
       }
-      $aclCategory = $config->data['OBJECTS'][$this->getType($this->dn)]['aclCategory'];
+      $aclCategory  = $config->data['OBJECTS'][$this->getType($this->dn)]['aclCategory'];
     }
 
-    if ($ui->allow_snapshot_restore($this->dn, $aclCategory)) {
+    if ($ui->allow_snapshot_restore($this->dn, $aclCategory, !count($target))) {
       @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->dn, 'Snaptshot restoring initiated!');
       $this->snapHandler->setSnapshotBases($bases);
       $this->dialogObject = new SnapshotRestoreDialog($this->dn, $this, !count($target), $aclCategory);
@@ -1273,7 +1273,7 @@ class simpleManagement
   function restoreSnapshot($dn)
   {
     global $ui;
-    if (!empty($dn) && $ui->allow_snapshot_restore($dn, $this->dialogObject->aclCategory)) {
+    if (!empty($dn) && $ui->allow_snapshot_restore($dn, $this->dialogObject->aclCategory, $this->dialogObject->global)) {
       $this->snapHandler->restoreSnapshot($dn);
       @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $dn, 'Snaptshot restored');
       $this->closeDialogs();
@@ -1319,7 +1319,14 @@ class simpleManagement
    */
   function removeSnapshot($dn)
   {
-    $this->snapHandler->removeSnapshot($dn);
+    global $ui;
+    if (!empty($dn) && $ui->allow_snapshot_delete($dn, $this->dialogObject->aclCategory)) {
+      $this->snapHandler->removeSnapshot($dn);
+      @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $dn, 'Snaptshot deleted');
+    } else {
+      msg_dialog::display(_('Permission'), sprintf(_('You are not allowed to delete a snapshot for %s.'), $dn),
+          ERROR_DIALOG);
+    }
   }
 
   static function mainInc ($classname)
diff --git a/include/simpleplugin/class_simpleSelectManagement.inc b/include/simpleplugin/class_simpleSelectManagement.inc
index 4f8aded09d10b517ee312a8e312f44ae1474158b..be53d884d3a2fd3d7abb81517d5ef3a2adf151b6 100644
--- a/include/simpleplugin/class_simpleSelectManagement.inc
+++ b/include/simpleplugin/class_simpleSelectManagement.inc
@@ -24,9 +24,10 @@ class simpleSelectManagement extends simpleManagement
   protected $skipHeader = TRUE;
 
   protected $skipCpHandler    = TRUE;
-  protected $skipSnapHandler  = TRUE;
   protected $autoActions      = FALSE;
 
+  public static $skipSnapshots = TRUE;
+
   protected $departmentRootVisible  = FALSE;
 
   function __construct()
diff --git a/plugins/admin/acl/class_aclManagement.inc b/plugins/admin/acl/class_aclManagement.inc
index ba429e6c8b01d449b1bb1f5c909e73e3cae84745..ce0b9656a1c4b4a1d8f3a6c27548eb096dc3d893 100644
--- a/plugins/admin/acl/class_aclManagement.inc
+++ b/plugins/admin/acl/class_aclManagement.inc
@@ -130,9 +130,10 @@ class aclManagement extends simpleManagement
   protected $departmentRootVisible  = FALSE;
   protected $baseMode               = FALSE;
   protected $skipCpHandler          = TRUE;
-  protected $skipSnapHandler        = TRUE;
   protected $autoActions            = FALSE;
 
+  public static $skipSnapshots = TRUE;
+
   static function plInfo()
   {
     return array(