1 <?php
2 /*
3 * This code is part of GOsa (http://www.gosa-project.org)
4 * Copyright (C) 2003-2008 GONICUS GmbH
5 *
6 * ID: $$Id$$
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
24 class SnapshotHandler {
26 var $config;
27 var $isEnabled= false;
28 var $snapshotBases= array();
31 /* Create handler */
32 function SnapshotHandler(&$config)
33 {
34 $this->config = &$config;
35 $config = $this->config;
37 if($config->get_cfg_value("enableSnapshots") == "true"){
39 /* Check if the snapshot_base is defined */
40 if ($config->get_cfg_value("snapshotBase") == ""){
42 /* Send message if not done already */
43 if(!session::is_set("snapshotFailMessageSend")){
44 session::set("snapshotFailMessageSend",TRUE);
45 msg_dialog::display(_("Configuration error"),
46 sprintf(_("The snapshot functionality is enabled, but the required variable '%s' is not set."),
47 "snapshotBase"), ERROR_DIALOG);
48 }
49 return;
50 }
52 /* Check if the snapshot_base is defined */
53 if (!is_callable("gzcompress")){
55 /* Send message if not done already */
56 if(!session::is_set("snapshotFailMessageSend")){
57 session::set("snapshotFailMessageSend",TRUE);
58 msg_dialog::display(_("Configuration error"),
59 sprintf(_("The snapshot functionality is enabled, but the required compression module is missing. Please install '%s'."),"php5-zip / php5-gzip"), ERROR_DIALOG);
60 }
61 return;
62 }
64 /* check if there are special server configurations for snapshots */
65 if ($config->get_cfg_value("snapshotURI") != ""){
67 /* check if all required vars are available to create a new ldap connection */
68 $missing = "";
69 foreach(array("snapshotURI","snapshotAdminDn","snapshotAdminPassword","snapshotBase") as $var){
70 if($config->get_cfg_value($var) == ""){
71 $missing .= $var." ";
73 /* Send message if not done already */
74 if(!session::is_set("snapshotFailMessageSend")){
75 session::set("snapshotFailMessageSend",TRUE);
76 msg_dialog::display(_("Configuration error"),
77 sprintf(_("The snapshot functionality is enabled, but the required variable '%s' is not set."),
78 $missing), ERROR_DIALOG);
79 }
80 return;
81 }
82 }
83 }
84 $this->isEnabled= true;
85 return;
86 }
87 }
90 function enabled()
91 {
92 return $this->isEnabled;
93 }
96 function setSnapshotBases($bases)
97 {
98 $this->snapshotBases= $bases;
99 }
102 function getSnapshotBases()
103 {
104 return $this->snapshotBases;
105 }
108 function get_snapshot_link()
109 {
110 $snapshotLdap= null;
112 /* check if there are special server configurations for snapshots */
113 if($this->config->get_cfg_value("snapshotURI") != ""){
114 $server= $this->config->get_cfg_value("snapshotURI");
115 $user= $this->config->get_cfg_value("snapshotAdminDn");
116 $password= $this->config->get_credentials($this->config->get_cfg_value("snapshotAdminPassword"));
117 $snapshotLdap= new ldapMultiplexer(new LDAP($user,$password, $server));
118 }
120 /* Prepare bases */
121 $this->snapshotLdapBase= $this->config->get_cfg_value("snapshotBase");
122 $snapshotLdap->cd($this->snapshotLdapBase);
123 if (!$snapshotLdap->success()){
124 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($snapshotLdap->get_error(), $this->snapshotLdapBase, "", get_class()));
125 }
127 return $snapshotLdap;
128 }
131 function getDeletedSnapshots($objectBase, $raw= false)
132 {
133 // Skip if not enabled
134 if(!$this->enabled()){
135 return(array());
136 }
138 // Load user info
139 $ui= get_userinfo();
141 /* Create an additional ldap object which
142 points to our ldap snapshot server */
143 $ldap= $this->config->get_ldap_link();
144 $ldap->cd($this->config->current['BASE']);
145 $snapshotLdap= $this->get_snapshot_link();
146 if (!$snapshotLdap) {
147 $snapshotLdap= $ldap;
148 }
150 // Initialize base
151 $base= preg_replace("/".preg_quote($this->config->current['BASE'], '/')."$/",
152 "", $objectBase).$this->snapshotLdapBase;
154 /* Fetch all objects and check if they do not exist anymore */
155 $objects= array();
156 $snapshotLdap->cd($base);
157 $snapshotLdap->ls("(objectClass=gosaSnapshotObject)", $base,
158 array("gosaSnapshotType", "gosaSnapshotTimestamp", "gosaSnapshotDN", "description"));
159 while($entry = $snapshotLdap->fetch()){
161 $chk = str_replace($base,"",$entry['dn']);
162 if(preg_match("/,ou=/",$chk)) continue;
164 if(!isset($entry['description'][0])){
165 $entry['description'][0] = "";
166 }
167 $objects[] = $entry;
168 }
170 /* Check if entry still exists */
171 foreach($objects as $key => $entry){
172 $ldap->cat($entry['gosaSnapshotDN'][0]);
173 if($ldap->count()){
174 unset($objects[$key]);
175 }
176 }
178 /* Format result as requested */
179 if($raw) {
180 return($objects);
181 }else{
182 $tmp = array();
183 foreach($objects as $key => $entry){
184 $tmp[base64_encode($entry['dn'])] = $entry['description'][0];
185 }
186 }
187 return($tmp);
188 }
191 function hasSnapshots($dn)
192 {
193 return (count($this->getSnapshots($dn)) > 0);
194 }
197 function getSnapshots($dn, $raw= false)
198 {
199 // Empty if disabled
200 if(!$this->enabled()){
201 return(array());
202 }
204 /* Create an additional ldap object which
205 points to our ldap snapshot server */
206 $ldap= $this->config->get_ldap_link();
207 $ldap->cd($this->config->current['BASE']);
209 // Load snapshot LDAP connection
210 $snapshotLdap= $this->get_snapshot_link();
211 if (!$snapshotLdap) {
212 $snapshotLdap= $ldap;
213 }
215 $objectBase= preg_replace("/^[^,]*./","",$dn);
217 // Initialize base
218 $base= preg_replace("/".preg_quote($this->config->current['BASE'], '/')."$/",
219 "", $objectBase).$this->snapshotLdapBase;
221 /* Fetch all objects with gosaSnapshotDN=$dn */
222 $snapshotLdap->cd($base);
223 $snapshotLdap->ls("(&(objectClass=gosaSnapshotObject)(gosaSnapshotDN=".$dn."))",$base,
224 array("gosaSnapshotType","gosaSnapshotTimestamp","gosaSnapshotDN","description"));
226 /* Put results into a list and add description if missing */
227 $objects= array();
228 while($entry = $snapshotLdap->fetch()){
229 if(!isset($entry['description'][0])){
230 $entry['description'][0] = "";
231 }
232 $objects[] = $entry;
233 }
235 /* Return the raw array, or format the result */
236 if($raw){
237 return($objects);
238 }else{
239 $tmp = array();
240 foreach($objects as $entry){
241 $tmp[base64_encode($entry['dn'])] = $entry['description'][0];
242 }
243 }
244 return($tmp);
245 }
248 /* Create a snapshot of the current object */
249 function create_snapshot($dn, $description= array())
250 {
252 /* Check if snapshot functionality is enabled */
253 if(!$this->snapshotEnabled()){
254 return;
255 }
257 /* Get configuration from gosa.conf */
258 $config = $this->config;
260 /* Create lokal ldap connection */
261 $ldap= $this->config->get_ldap_link();
262 $ldap->cd($this->config->current['BASE']);
264 /* check if there are special server configurations for snapshots */
265 if($config->get_cfg_value("snapshotURI") == ""){
267 /* Source and destination server are both the same, just copy source to dest obj */
268 $ldap_to = $ldap;
269 $snapldapbase = $this->config->current['BASE'];
271 }else{
272 $server = $config->get_cfg_value("snapshotURI");
273 $user = $config->get_cfg_value("snapshotAdminDn");
274 $password = $this->config->get_credentials($config->get_cfg_value("snapshotAdminPassword"));
275 $snapldapbase = $config->get_cfg_value("snapshotBase");
277 $ldap_to = new ldapMultiplexer(new LDAP($user,$password, $server));
278 $ldap_to -> cd($snapldapbase);
280 if (!$ldap_to->success()){
281 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
282 }
284 }
286 /* check if the dn exists */
287 if ($ldap->dn_exists($dn)){
289 /* Extract seconds & mysecs, they are used as entry index */
290 list($usec, $sec)= explode(" ", microtime());
292 /* Collect some infos */
293 $base = $this->config->current['BASE'];
294 $snap_base = $config->get_cfg_value("snapshotBase");
295 $base_of_object = preg_replace ('/^[^,]+,/i', '', $dn);
296 $new_base = preg_replace("/".preg_quote($base, '/')."$/","",$base_of_object).$snap_base;
298 /* Create object */
299 #$data = preg_replace('/^dn:.*\n/', '', $ldap->gen_ldif($dn,"(!(objectClass=gosaDepartment))"));
300 $data = $ldap->gen_ldif($dn,"(&(!(objectClass=gosaDepartment))(!(objectClass=FAIclass)))");
301 $newName = str_replace(".", "", $sec."-".$usec);
302 $target= array();
303 $target['objectClass'] = array("top", "gosaSnapshotObject");
304 $target['gosaSnapshotData'] = gzcompress($data, 6);
305 $target['gosaSnapshotType'] = "snapshot";
306 $target['gosaSnapshotDN'] = $dn;
307 $target['description'] = $description;
308 $target['gosaSnapshotTimestamp'] = $newName;
310 /* Insert the new snapshot
311 But we have to check first, if the given gosaSnapshotTimestamp
312 is already used, in this case we should increment this value till there is
313 an unused value. */
314 $new_dn = "gosaSnapshotTimestamp=".$newName.",".$new_base;
315 $ldap_to->cat($new_dn);
316 while($ldap_to->count()){
317 $ldap_to->cat($new_dn);
318 $newName = str_replace(".", "", $sec."-".($usec++));
319 $new_dn = "gosaSnapshotTimestamp=".$newName.",".$new_base;
320 $target['gosaSnapshotTimestamp'] = $newName;
321 }
322 /* Inset this new snapshot */
323 $ldap_to->cd($snapldapbase);
324 $ldap_to->create_missing_trees($snapldapbase);
325 $ldap_to->create_missing_trees($new_base);
326 $ldap_to->cd($new_dn);
327 $ldap_to->add($target);
328 if (!$ldap_to->success()){
329 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $new_dn, LDAP_ADD, get_class()));
330 }
332 if (!$ldap->success()){
333 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $new_base, "", get_class()));
334 }
336 }
337 }
339 function remove_snapshot($dn)
340 {
341 $ui = get_userinfo();
342 $old_dn = $this->dn;
343 $this->dn = $dn;
344 $ldap = $this->config->get_ldap_link();
345 $ldap->cd($this->config->current['BASE']);
346 $ldap->rmdir_recursive($this->dn);
347 if(!$ldap->success()){
348 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn));
349 }
350 $this->dn = $old_dn;
351 }
352 /* returns true if snapshots are enabled, and false if it is disalbed
353 There will also be some errors psoted, if the configuration failed */
354 function snapshotEnabled()
355 {
356 return $this->config->snapshotEnabled();
357 }
360 /* Return available snapshots for the given base
361 */
362 function Available_SnapsShots($dn,$raw = false)
363 {
364 if(!$this->snapshotEnabled()) return(array());
366 /* Create an additional ldap object which
367 points to our ldap snapshot server */
368 $ldap= $this->config->get_ldap_link();
369 $ldap->cd($this->config->current['BASE']);
370 $cfg= &$this->config->current;
372 /* check if there are special server configurations for snapshots */
373 if($this->config->get_cfg_value("snapshotURI") == ""){
374 $ldap_to = $ldap;
375 }else{
376 $server = $this->config->get_cfg_value("snapshotURI");
377 $user = $this->config->get_cfg_value("snapshotAdminDn");
378 $password = $this->config->get_credentials($this->config->get_cfg_value("snapshotAdminPassword"));
379 $snapldapbase = $this->config->get_cfg_value("snapshotBase");
380 $ldap_to = new ldapMultiplexer(new LDAP($user,$password, $server));
381 $ldap_to -> cd($snapldapbase);
382 if (!$ldap_to->success()){
383 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
384 }
385 }
386 /* Prepare bases and some other infos */
387 $base = $this->config->current['BASE'];
388 $snap_base = $this->config->get_cfg_value("snapshotBase");
389 $base_of_object = preg_replace ('/^[^,]+,/i', '', $dn);
390 $new_base = preg_replace("/".preg_quote($base, '/')."$/","",$base_of_object).$snap_base;
391 $tmp = array();
393 /* Fetch all objects with gosaSnapshotDN=$dn */
394 $ldap_to->cd($new_base);
395 $ldap_to->ls("(&(objectClass=gosaSnapshotObject)(gosaSnapshotDN=".$dn."))",$new_base,
396 array("gosaSnapshotType","gosaSnapshotTimestamp","gosaSnapshotDN","description"));
398 /* Put results into a list and add description if missing */
399 while($entry = $ldap_to->fetch()){
400 if(!isset($entry['description'][0])){
401 $entry['description'][0] = "";
402 }
403 $tmp[] = $entry;
404 }
406 /* Return the raw array, or format the result */
407 if($raw){
408 return($tmp);
409 }else{
410 $tmp2 = array();
411 foreach($tmp as $entry){
412 $tmp2[base64_encode($entry['dn'])] = $entry['description'][0];
413 }
414 }
415 return($tmp2);
416 }
417 function getAllDeletedSnapshots($base_of_object,$raw = false)
418 {
419 if(!$this->snapshotEnabled()) return(array());
421 /* Create an additional ldap object which
422 points to our ldap snapshot server */
423 $ldap= $this->config->get_ldap_link();
424 $ldap->cd($this->config->current['BASE']);
425 $cfg= &$this->config->current;
427 /* check if there are special server configurations for snapshots */
428 if($this->config->get_cfg_value("snapshotURI") == ""){
429 $ldap_to = $ldap;
430 }else{
431 $server = $this->config->get_cfg_value("snapshotURI");
432 $user = $this->config->get_cfg_value("snapshotAdminDn");
433 $password = $this->config->get_credentials($this->config->get_cfg_value("snapshotAdminPassword"));
434 $snapldapbase = $this->config->get_cfg_value("snapshotBase");
435 $ldap_to = new ldapMultiplexer(new LDAP($user,$password, $server));
436 $ldap_to -> cd($snapldapbase);
437 if (!$ldap_to->success()){
438 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
439 }
440 }
442 /* Prepare bases */
443 $base = $this->config->current['BASE'];
444 $snap_base = $this->config->get_cfg_value("snapshotBase");
445 $new_base = preg_replace("/".preg_quote($base, '/')."$/","",$base_of_object).$snap_base;
446 /* Fetch all objects and check if they do not exist anymore */
447 $ui = get_userinfo();
448 $tmp = array();
449 $ldap_to->cd($new_base);
450 $ldap_to->ls("(objectClass=gosaSnapshotObject)",$new_base,array("gosaSnapshotType","gosaSnapshotTimestamp","gosaSnapshotDN","description"));
451 while($entry = $ldap_to->fetch()){
453 $chk = str_replace($new_base,"",$entry['dn']);
454 if(preg_match("/,ou=/",$chk)) continue;
456 if(!isset($entry['description'][0])){
457 $entry['description'][0] = "";
458 }
459 $tmp[] = $entry;
460 }
462 /* Check if entry still exists */
463 foreach($tmp as $key => $entry){
464 $ldap->cat($entry['gosaSnapshotDN'][0]);
465 if($ldap->count()){
466 unset($tmp[$key]);
467 }
468 }
470 /* Format result as requested */
471 if($raw) {
472 return($tmp);
473 }else{
474 $tmp2 = array();
475 foreach($tmp as $key => $entry){
476 $tmp2[base64_encode($entry['dn'])] = $entry['description'][0];
477 }
478 }
479 return($tmp2);
480 }
483 /* Restore selected snapshot */
484 function restore_snapshot($dn)
485 {
486 if(!$this->snapshotEnabled()) return(array());
488 $ldap= $this->config->get_ldap_link();
489 $ldap->cd($this->config->current['BASE']);
490 $cfg= &$this->config->current;
492 /* check if there are special server configurations for snapshots */
493 if($this->config->get_cfg_value("snapshotURI") == ""){
494 $ldap_to = $ldap;
495 }else{
496 $server = $this->config->get_cfg_value("snapshotURI");
497 $user = $this->config->get_cfg_value("snapshotAdminDn");
498 $password = $this->config->get_credentials($this->config->get_cfg_value("snapshotAdminPassword"));
499 $snapldapbase = $this->config->get_cfg_value("snapshotBase");
500 $ldap_to = new ldapMultiplexer(new LDAP($user,$password, $server));
501 $ldap_to -> cd($snapldapbase);
502 if (!$ldap_to->success()){
503 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
504 }
505 }
507 /* Get the snapshot */
508 $ldap_to->cat($dn);
509 $restoreObject = $ldap_to->fetch();
511 /* Prepare import string */
512 $data = gzuncompress($ldap_to->get_attribute($dn,'gosaSnapshotData'));
514 /* Import the given data */
515 $err = "";
516 $ldap->import_complete_ldif($data,$err,false,false);
517 if (!$ldap->success()){
518 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, "", get_class()));
519 }
520 }
523 }
524 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
525 ?>