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();
30 /* Create handler */
31 function SnapshotHandler(&$config)
32 {
33 $this->config = &$config;
34 $config = $this->config;
36 if($config->get_cfg_value("core","enableSnapshots") == "true"){
38 /* Check if the snapshot_base is defined */
39 if ($config->get_cfg_value("core","snapshotBase") == ""){
41 /* Send message if not done already */
42 if(!session::is_set("snapshotFailMessageSend")){
43 session::set("snapshotFailMessageSend",TRUE);
44 msg_dialog::display(_("Configuration error"),
45 sprintf(_("The snapshot functionality is enabled but the required variable %s is not set!"),
46 bold("snapshotBase")), ERROR_DIALOG);
47 }
48 return;
49 }
51 /* Check if the snapshot_base is defined */
52 if (!is_callable("gzcompress")){
54 /* Send message if not done already */
55 if(!session::is_set("snapshotFailMessageSend")){
56 session::set("snapshotFailMessageSend",TRUE);
57 msg_dialog::display(_("Configuration error"),
58 sprintf(_("The snapshot functionality is enabled but the required PHP compression module is missing: %s!"), bold("php5-zip / php5-gzip")), ERROR_DIALOG);
59 }
60 return;
61 }
63 /* check if there are special server configurations for snapshots */
64 if ($config->get_cfg_value("core","snapshotURI") != ""){
66 /* check if all required vars are available to create a new ldap connection */
67 $missing = "";
68 foreach(array("snapshotURI","snapshotAdminDn","snapshotAdminPassword","snapshotBase") as $var){
69 if($config->get_cfg_value("core",$var) == ""){
70 $missing .= $var." ";
72 /* Send message if not done already */
73 if(!session::is_set("snapshotFailMessageSend")){
74 session::set("snapshotFailMessageSend",TRUE);
75 msg_dialog::display(_("Configuration error"),
76 sprintf(_("The snapshot functionality is enabled but the required variable %s is not set!"),
77 bold($missing)), ERROR_DIALOG);
78 }
79 return;
80 }
81 }
82 }
83 $this->isEnabled= true;
84 return;
85 }
86 }
89 function enabled()
90 {
91 return $this->isEnabled;
92 }
95 function setSnapshotBases($bases)
96 {
97 $this->snapshotBases= $bases;
98 }
101 function getSnapshotBases()
102 {
103 return $this->snapshotBases;
104 }
107 function get_snapshot_link()
108 {
109 $snapshotLdap= null;
111 /* check if there are special server configurations for snapshots */
112 if($this->config->get_cfg_value("core","snapshotURI") != ""){
113 $server= $this->config->get_cfg_value("core","snapshotURI");
114 $user= $this->config->get_cfg_value("core","snapshotAdminDn");
115 $password= $this->config->get_credentials($this->config->get_cfg_value("core","snapshotAdminPassword"));
116 $snapshotLdap= new ldapMultiplexer(new LDAP($user,$password, $server));
117 }
119 /* Prepare bases */
120 $this->snapshotLdapBase= $this->config->get_cfg_value("core","snapshotBase");
121 $snapshotLdap->cd($this->snapshotLdapBase);
122 if (!$snapshotLdap->success()){
123 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($snapshotLdap->get_error(), $this->snapshotLdapBase, "", get_class()));
124 }
126 return $snapshotLdap;
127 }
130 function getDeletedSnapshots($objectBase, $raw= false)
131 {
132 // Skip if not enabled
133 if(!$this->enabled()){
134 return(array());
135 }
137 // Load user info
138 $ui= get_userinfo();
140 /* Create an additional ldap object which
141 points to our ldap snapshot server */
142 $ldap= $this->config->get_ldap_link();
143 $ldap->cd($this->config->current['BASE']);
144 $snapshotLdap= $this->get_snapshot_link();
145 if (!$snapshotLdap) {
146 $snapshotLdap= $ldap;
147 }
149 // Initialize base
150 $base= preg_replace("/".preg_quote($this->config->current['BASE'], '/')."$/",
151 "", $objectBase).$this->snapshotLdapBase;
153 /* Fetch all objects and check if they do not exist anymore */
154 $objects= array();
155 $snapshotLdap->cd($base);
156 $snapshotLdap->ls("(objectClass=gosaSnapshotObject)", $base,
157 array("gosaSnapshotType", "gosaSnapshotTimestamp", "gosaSnapshotDN", "description"));
158 while($entry = $snapshotLdap->fetch()){
160 $chk = str_replace($base,"",$entry['dn']);
161 if(preg_match("/,ou=/",$chk)) continue;
163 if(!isset($entry['description'][0])){
164 $entry['description'][0] = "";
165 }
166 $objects[] = $entry;
167 }
169 /* Check if entry still exists */
170 foreach($objects as $key => $entry){
171 $ldap->cat($entry['gosaSnapshotDN'][0]);
172 if($ldap->count()){
173 unset($objects[$key]);
174 }
175 }
177 /* Format result as requested */
178 if($raw) {
179 return($objects);
180 }else{
181 $tmp = array();
182 foreach($objects as $key => $entry){
183 $tmp[base64_encode($entry['dn'])] = $entry['description'][0];
184 }
185 }
186 return($tmp);
187 }
190 function hasSnapshots($dn)
191 {
192 return (count($this->getSnapshots($dn)) > 0);
193 }
196 function getSnapshots($dn, $raw= false)
197 {
198 // Empty if disabled
199 if(!$this->enabled()){
200 return(array());
201 }
203 /* Create an additional ldap object which
204 points to our ldap snapshot server */
205 $ldap= $this->config->get_ldap_link();
206 $ldap->cd($this->config->current['BASE']);
208 // Load snapshot LDAP connection
209 $snapshotLdap= $this->get_snapshot_link();
210 if (!$snapshotLdap) {
211 $snapshotLdap= $ldap;
212 }
214 $objectBase= preg_replace("/^[^,]*./","",$dn);
216 // Initialize base
217 $base= preg_replace("/".preg_quote($this->config->current['BASE'], '/')."$/",
218 "", $objectBase).$this->snapshotLdapBase;
220 /* Fetch all objects with gosaSnapshotDN=$dn */
221 $snapshotLdap->cd($base);
222 $snapshotLdap->ls("(&(objectClass=gosaSnapshotObject)(gosaSnapshotDN=".$dn."))",$base,
223 array("gosaSnapshotType","gosaSnapshotTimestamp","gosaSnapshotDN","description"));
225 /* Put results into a list and add description if missing */
226 $objects= array();
227 while($entry = $snapshotLdap->fetch()){
228 if(!isset($entry['description'][0])){
229 $entry['description'][0] = "";
230 }
231 $objects[] = $entry;
232 }
234 /* Return the raw array, or format the result */
235 if($raw){
236 return($objects);
237 }else{
238 $tmp = array();
239 foreach($objects as $entry){
240 $tmp[base64_encode($entry['dn'])] = $entry['description'][0];
241 }
242 }
243 return($tmp);
244 }
247 /* Create a snapshot of the current object */
248 function create_snapshot($dn, $description= array())
249 {
251 /* Check if snapshot functionality is enabled */
252 if(!$this->snapshotEnabled()){
253 return;
254 }
256 /* Get configuration from gosa.conf */
257 $config = $this->config;
259 /* Create lokal ldap connection */
260 $ldap= $this->config->get_ldap_link();
261 $ldap->cd($this->config->current['BASE']);
263 /* check if there are special server configurations for snapshots */
264 if($config->get_cfg_value("core","snapshotURI") == ""){
266 /* Source and destination server are both the same, just copy source to dest obj */
267 $ldap_to = $ldap;
268 $snapldapbase = $this->config->current['BASE'];
270 }else{
271 $server = $config->get_cfg_value("core","snapshotURI");
272 $user = $config->get_cfg_value("core","snapshotAdminDn");
273 $password = $this->config->get_credentials($config->get_cfg_value("core","snapshotAdminPassword"));
274 $snapldapbase = $config->get_cfg_value("core","snapshotBase");
276 $ldap_to = new ldapMultiplexer(new LDAP($user,$password, $server));
277 $ldap_to -> cd($snapldapbase);
279 if (!$ldap_to->success()){
280 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
281 }
283 }
285 /* check if the dn exists */
286 if ($ldap->dn_exists($dn)){
288 /* Extract seconds & mysecs, they are used as entry index */
289 list($usec, $sec)= explode(" ", microtime());
291 /* Collect some infos */
292 $base = $this->config->current['BASE'];
293 $snap_base = $config->get_cfg_value("core","snapshotBase");
294 $base_of_object = preg_replace ('/^[^,]+,/i', '', $dn);
295 $new_base = preg_replace("/".preg_quote($base, '/')."$/","",$base_of_object).$snap_base;
297 /* Create object */
298 $data = $ldap->generateLdif(LDAP::fix($dn),
299 "(&(!(objectClass=gosaDepartment))(!(objectClass=FAIclass)))",'base');
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 $ldap = $this->config->get_ldap_link();
343 $ldap->cd($this->config->current['BASE']);
344 $ldap->rmdir_recursive($dn);
345 if(!$ldap->success()){
346 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn));
347 }
348 }
349 /* returns true if snapshots are enabled, and false if it is disalbed
350 There will also be some errors psoted, if the configuration failed */
351 function snapshotEnabled()
352 {
353 return $this->config->snapshotEnabled();
354 }
357 /* Return available snapshots for the given base
358 */
359 function Available_SnapsShots($dn,$raw = false)
360 {
361 if(!$this->snapshotEnabled()) return(array());
363 /* Create an additional ldap object which
364 points to our ldap snapshot server */
365 $ldap= $this->config->get_ldap_link();
366 $ldap->cd($this->config->current['BASE']);
367 $cfg= &$this->config->current;
369 /* check if there are special server configurations for snapshots */
370 if($this->config->get_cfg_value("core","snapshotURI") == ""){
371 $ldap_to = $ldap;
372 }else{
373 $server = $this->config->get_cfg_value("core","snapshotURI");
374 $user = $this->config->get_cfg_value("core","snapshotAdminDn");
375 $password = $this->config->get_credentials($this->config->get_cfg_value("core","snapshotAdminPassword"));
376 $snapldapbase = $this->config->get_cfg_value("core","snapshotBase");
377 $ldap_to = new ldapMultiplexer(new LDAP($user,$password, $server));
378 $ldap_to -> cd($snapldapbase);
379 if (!$ldap_to->success()){
380 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
381 }
382 }
383 /* Prepare bases and some other infos */
384 $base = $this->config->current['BASE'];
385 $snap_base = $this->config->get_cfg_value("core","snapshotBase");
386 $base_of_object = preg_replace ('/^[^,]+,/i', '', $dn);
387 $new_base = preg_replace("/".preg_quote($base, '/')."$/","",$base_of_object).$snap_base;
388 $tmp = array();
390 /* Fetch all objects with gosaSnapshotDN=$dn */
391 $ldap_to->cd($new_base);
392 $ldap_to->ls("(&(objectClass=gosaSnapshotObject)(gosaSnapshotDN=".$dn."))",$new_base,
393 array("gosaSnapshotType","gosaSnapshotTimestamp","gosaSnapshotDN","description"));
395 /* Put results into a list and add description if missing */
396 while($entry = $ldap_to->fetch()){
397 if(!isset($entry['description'][0])){
398 $entry['description'][0] = "";
399 }
400 $tmp[] = $entry;
401 }
403 /* Return the raw array, or format the result */
404 if($raw){
405 return($tmp);
406 }else{
407 $tmp2 = array();
408 foreach($tmp as $entry){
409 $tmp2[base64_encode($entry['dn'])] = $entry['description'][0];
410 }
411 }
412 return($tmp2);
413 }
414 function getAllDeletedSnapshots($base_of_object,$raw = false)
415 {
416 if(!$this->snapshotEnabled()) return(array());
418 /* Create an additional ldap object which
419 points to our ldap snapshot server */
420 $ldap= $this->config->get_ldap_link();
421 $ldap->cd($this->config->current['BASE']);
422 $cfg= &$this->config->current;
424 /* check if there are special server configurations for snapshots */
425 if($this->config->get_cfg_value("core","snapshotURI") == ""){
426 $ldap_to = $ldap;
427 }else{
428 $server = $this->config->get_cfg_value("core","snapshotURI");
429 $user = $this->config->get_cfg_value("core","snapshotAdminDn");
430 $password = $this->config->get_credentials($this->config->get_cfg_value("core","snapshotAdminPassword"));
431 $snapldapbase = $this->config->get_cfg_value("core","snapshotBase");
432 $ldap_to = new ldapMultiplexer(new LDAP($user,$password, $server));
433 $ldap_to -> cd($snapldapbase);
434 if (!$ldap_to->success()){
435 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
436 }
437 }
439 /* Prepare bases */
440 $base = $this->config->current['BASE'];
441 $snap_base = $this->config->get_cfg_value("core","snapshotBase");
442 $new_base = preg_replace("/".preg_quote($base, '/')."$/","",$base_of_object).$snap_base;
443 /* Fetch all objects and check if they do not exist anymore */
444 $ui = get_userinfo();
445 $tmp = array();
446 $ldap_to->cd($new_base);
447 $ldap_to->ls("(objectClass=gosaSnapshotObject)",$new_base,array("gosaSnapshotType","gosaSnapshotTimestamp","gosaSnapshotDN","description"));
448 while($entry = $ldap_to->fetch()){
450 $chk = str_replace($new_base,"",$entry['dn']);
451 if(preg_match("/,ou=/",$chk)) continue;
453 if(!isset($entry['description'][0])){
454 $entry['description'][0] = "";
455 }
456 $tmp[] = $entry;
457 }
459 /* Check if entry still exists */
460 foreach($tmp as $key => $entry){
461 $ldap->cat($entry['gosaSnapshotDN'][0]);
462 if($ldap->count()){
463 unset($tmp[$key]);
464 }
465 }
467 /* Format result as requested */
468 if($raw) {
469 return($tmp);
470 }else{
471 $tmp2 = array();
472 foreach($tmp as $key => $entry){
473 $tmp2[base64_encode($entry['dn'])] = $entry['description'][0];
474 }
475 }
476 return($tmp2);
477 }
480 /* Restore selected snapshot */
481 function restore_snapshot($dn)
482 {
483 if(!$this->snapshotEnabled()) return(array());
485 $ldap= $this->config->get_ldap_link();
486 $ldap->cd($this->config->current['BASE']);
487 $cfg= &$this->config->current;
489 /* check if there are special server configurations for snapshots */
490 if($this->config->get_cfg_value("core","snapshotURI") == ""){
491 $ldap_to = $ldap;
492 }else{
493 $server = $this->config->get_cfg_value("core","snapshotURI");
494 $user = $this->config->get_cfg_value("core","snapshotAdminDn");
495 $password = $this->config->get_credentials($this->config->get_cfg_value("core","snapshotAdminPassword"));
496 $snapldapbase = $this->config->get_cfg_value("core","snapshotBase");
497 $ldap_to = new ldapMultiplexer(new LDAP($user,$password, $server));
498 $ldap_to -> cd($snapldapbase);
499 if (!$ldap_to->success()){
500 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
501 }
502 }
504 /* Get the snapshot */
505 $ldap_to->cat($dn);
506 $restoreObject = $ldap_to->fetch();
508 /* Prepare import string */
509 $data = gzuncompress($ldap_to->get_attribute($dn,'gosaSnapshotData'));
511 /* Import the given data */
512 $err = "";
513 $ldap->import_complete_ldif($data,$err,false,false);
514 if (!$ldap->success()){
515 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, "", get_class()));
516 }
517 }
520 }
521 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
522 ?>