FusionDirectory
 All Data Structures Files Functions Variables
class_SnapshotHandler.inc
1 <?php
2 /*
3  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
4  Copyright (C) 2003-2010 Cajus Pollmeier
5  Copyright (C) 2011-2016 FusionDirectory
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 
22 /*
23  * \file class_SnapshotHandler
24  * Source code for class SnapshotHandler
25  */
26 
32 {
33  var $snapshotBases = array();
34 
35  protected $enabled;
36 
42  function __construct()
43  {
44  global $config;
45  $this->enabled = $config->snapshotEnabled();
46  if ($this->enabled) {
47  /* Prepare base */
48  $this->snapshotRDN = $config->get_cfg_value('snapshotBase');
49  $ldap = $config->get_ldap_link();
50  $ldap->cd($config->current['BASE']);
51  $ldap->create_missing_trees($this->snapshotRDN);
52  if (!$ldap->success()) {
53  msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), $this->snapshotRDN, '', get_class()), LDAP_ERROR);
54  }
55  }
56  }
57 
63  function enabled()
64  {
65  return $this->enabled;
66  }
67 
73  function setSnapshotBases($bases)
74  {
75  $this->snapshotBases = $bases;
76  }
77 
83  function getSnapshotBases()
84  {
85  return $this->snapshotBases;
86  }
87 
88  /* \brief Get the snapshot dn of an object dn
89  */
90  protected function snapshot_dn($dn)
91  {
92  global $config;
93  return preg_replace("/".preg_quote($config->current['BASE'], '/')."$/", "", $dn)
94  .$this->snapshotRDN;
95  }
96 
101  {
102  foreach ($this->getSnapshotBases() as $base) {
103  if (count($this->getAllDeletedSnapshots($base)) > 0) {
104  return TRUE;
105  }
106  }
107  return FALSE;
108  }
109 
113  function initSnapshotCache($base)
114  {
115  global $config;
116  if (!$this->enabled()) {
117  return;
118  }
119 
120  $ldap = $config->get_ldap_link();
121 
122  // Initialize base
123  $base = $this->snapshot_dn($base);
124 
125  /* Fetch all objects with */
126  $ldap->cd($base);
127  $ldap->search('(&(objectClass=gosaSnapshotObject)(gosaSnapshotDN=*))', array('gosaSnapshotDN'));
128 
129  /* Store for which object we have snapshots */
130  $this->snapshotsCache = array();
131  while ($entry = $ldap->fetch()) {
132  $this->snapshotsCache[$entry['gosaSnapshotDN'][0]] = TRUE;
133  }
134  }
135 
141  function hasSnapshots($dn)
142  {
143  return (isset($this->snapshotsCache[$dn]));
144  }
145 
153  function getSnapshots($dn, $raw = FALSE)
154  {
155  global $config;
156  if (!$this->enabled()) {
157  return array();
158  }
159 
160  $ldap = $config->get_ldap_link();
161 
162  $objectBase = preg_replace("/^[^,]*./", "", $dn);
163 
164  // Initialize base
165  $base = $this->snapshot_dn($objectBase);
166 
167  /* Fetch all objects with gosaSnapshotDN=$dn */
168  $ldap->cd($base);
169  $ldap->search(
170  '(&(objectClass=gosaSnapshotObject)(gosaSnapshotDN='.ldap_escape_f($dn).'))',
171  array('gosaSnapshotTimestamp','gosaSnapshotDN','description'),
172  'one'
173  );
174 
175  /* Put results into a list and add description if missing */
176  $objects = array();
177  while ($entry = $ldap->fetch()) {
178  if (!isset($entry['description'][0])) {
179  $entry['description'][0] = "";
180  }
181  $objects[] = $entry;
182  }
183 
184  /* Return the raw array, or format the result */
185  if ($raw) {
186  return $objects;
187  } else {
188  $tmp = array();
189  foreach ($objects as $entry) {
190  $tmp[base64_encode($entry['dn'])] = $entry['description'][0];
191  }
192  }
193  return $tmp;
194  }
195 
196 
204  function createSnapshot($dn, $description = array())
205  {
206  global $config;
207  if (!$this->enabled()) {
208  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $dn, 'Snaptshot are disabled but tried to create snapshot');
209  return;
210  }
211 
212  if (is_array($dn)) {
213  $dns = $dn;
214  $dn = $dns[0];
215  } else {
216  $dns = array($dn);
217  }
218 
219  $ldap = $config->get_ldap_link();
220 
221  /* check if the dn exists */
222  if (!$ldap->dn_exists($dn)) {
223  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $dn, 'Tried to snapshot non-existing dn');
224  return;
225  }
226 
227  /* Extract seconds & mysecs, they are used as entry index */
228  list($usec, $sec) = explode(" ", microtime());
229 
230  /* Collect some infos */
231  $base_of_object = preg_replace ('/^[^,]+,/i', '', $dn);
232  $new_base = $this->snapshot_dn($base_of_object);
233  /* Create object */
234  $data = '';
235  foreach ($dns as $tmp_dn) {
236  $data .= $ldap->generateLdif($tmp_dn, '(!(objectClass=gosaDepartment))', 'sub');
237  if (!$ldap->success()) {
238  msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), $tmp_dn, '', get_class()), LDAP_ERROR);
239  }
240  }
241 
242  $target = array();
243 
244  $target['objectClass'] = array('top', 'gosaSnapshotObject');
245  $target['gosaSnapshotData'] = gzcompress($data, 6);
246  $target['gosaSnapshotDN'] = $dn;
247  $target['description'] = $description;
248 
249  /* Insert the new snapshot
250  But we have to check first, if the given gosaSnapshotTimestamp
251  is already used, in this case we should increment this value till there is
252  an unused value. */
253  do {
254  $target['gosaSnapshotTimestamp'] = str_replace('.', '', $sec.'-'.$usec);
255  $new_dn = 'gosaSnapshotTimestamp='.$target['gosaSnapshotTimestamp'].','.$new_base;
256  $ldap->cat($new_dn);
257  $usec++;
258  } while ($ldap->count());
259 
260  /* Insert this new snapshot */
261  $ldap->cd($this->snapshotRDN);
262  $ldap->create_missing_trees($this->snapshotRDN);
263  $ldap->create_missing_trees($new_base);
264  $ldap->cd($new_dn);
265  $ldap->add($target);
266 
267  if (!$ldap->success()) {
268  msg_dialog::display(_('LDAP error'), msgPool::ldaperror($ldap->get_error(), $new_base, '', get_class()), LDAP_ERROR);
269  }
270  }
271 
277  function removeSnapshot($dn)
278  {
279  global $config;
280  $ldap = $config->get_ldap_link();
281  $ldap->cd($config->current['BASE']);
282  $ldap->rmdir_recursive($dn);
283  if (!$ldap->success()) {
284  msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn), LDAP_ERROR);
285  }
286  }
287 
294  {
295  global $config;
296  if (!$this->enabled()) {
297  return array();
298  }
299 
300  $ldap = $config->get_ldap_link();
301 
302  /* Prepare bases and some other infos */
303  $base_of_object = preg_replace ('/^[^,]+,/i', '', $dn);
304  $new_base = $this->snapshot_dn($base_of_object);
305  $tmp = array();
306 
307  /* Fetch all objects with gosaSnapshotDN=$dn */
308  $ldap->cd($new_base);
309  $ldap->search(
310  '(&(objectClass=gosaSnapshotObject)(gosaSnapshotDN='.ldap_escape_f($dn).'))',
311  array('gosaSnapshotTimestamp','gosaSnapshotDN','description'),
312  'one'
313  );
314 
315  /* Put results into a list and add description if missing */
316  while ($entry = $ldap->fetch()) {
317  if (!isset($entry['description'][0])) {
318  $entry['description'][0] = "";
319  }
320  $tmp[] = $entry;
321  }
322 
323  return $tmp;
324  }
325 
333  function getAllDeletedSnapshots($base_of_object)
334  {
335  global $config;
336  if (!$this->enabled()) {
337  return array();
338  }
339 
340  $ldap = $config->get_ldap_link();
341 
342  /* Prepare bases */
343  $new_base = $this->snapshot_dn($base_of_object);
344  /* Fetch all objects and check if they do not exist anymore */
345  $tmp = array();
346  $ldap->cd($new_base);
347  $ldap->search(
348  '(objectClass=gosaSnapshotObject)',
349  array('gosaSnapshotTimestamp','gosaSnapshotDN','description'),
350  'one'
351  );
352  while ($entry = $ldap->fetch()) {
353  $chk = str_replace($new_base, "", $entry['dn']);
354  if (preg_match("/,ou=/", $chk)) {
355  continue;
356  }
357 
358  if (!isset($entry['description'][0])) {
359  $entry['description'][0] = "";
360  }
361  $tmp[] = $entry;
362  }
363 
364  /* Check if entry still exists */
365  foreach ($tmp as $key => $entry) {
366  $ldap->cat($entry['gosaSnapshotDN'][0]);
367  if ($ldap->count()) {
368  unset($tmp[$key]);
369  }
370  }
371 
372  return $tmp;
373  }
374 
375 
381  function restoreSnapshot($dn)
382  {
383  global $config;
384  if (!$this->enabled()) {
385  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $dn, 'Snaptshot are disabled but tried to restore snapshot');
386  return array();
387  }
388 
389  $ldap = $config->get_ldap_link();
390 
391  /* Get the snapshot */
392  $ldap->cat($dn);
393  $ldap->fetch();
394 
395  /* Prepare import string */
396  $data = gzuncompress($ldap->get_attribute($dn, 'gosaSnapshotData'));
397  if ($data === FALSE) {
398  msg_dialog::display(_('Error'), _('There was a problem uncompressing snapshot data'), ERROR_DIALOG);
399  }
400 
401  /* Import the given data */
402  try {
403  $ldap->import_complete_ldif($data, FALSE, FALSE);
404  if (!$ldap->success()) {
405  msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, "", get_class()), LDAP_ERROR);
406  }
407  } catch (LDIFImportException $e) {
408  msg_dialog::display(_('LDAP error'), $e->getMessage(), ERROR_DIALOG);
409  }
410  }
411 }
412 ?>
static ldaperror($error, $dn= '', $type=0, $plugin= '')
Display LDAP error.
getAvailableSnapsShots($dn)
Get the available snapshots.
enabled()
Check if the snapshot is enable.
getSnapshots($dn, $raw=FALSE)
Get snapshots.
initSnapshotCache($base)
Cache Snapshot information for all objects in $base.
createSnapshot($dn, $description=array())
Create a snapshot of the current object.
setSnapshotBases($bases)
Set a new snapshot bases.
DEBUG($level, $line, $function, $file, $data, $info= '')
Debug level action.
Definition: functions.inc:219
hasDeletedSnapshots()
Check if there are deleted snapshots.
getSnapshotBases()
Get the current snapshot bases.
getAllDeletedSnapshots($base_of_object)
Get all deleted snapshots.
This class contains all the function needed to handle the snapshot functionality. ...
removeSnapshot($dn)
Remove a snapshot.
static display($s_title, $s_message, $i_type=INFO_DIALOG)
Display a message dialog.
restoreSnapshot($dn)
Restore selected snapshot.
Exception class which can be thrown by LDAP if the LDIF format is broken.
__construct()
Create handler.
hasSnapshots($dn)
Check if the DN has snapshots.