Code

1f0c472b87e68386991070618ef178049f7471f6
[gosa.git] / gosa-plugins / systems / admin / systems / class_systemManagement.inc
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 #
25 # NewDevices 
26 # -> Edit
27 # ->  |- SelectDeviceType()       (Allows to select target SystemType and OGroup)
28 # -> Save
29 #     |-> systemTypeChosen()       (Queue entry to be activated) 
30 #     |-> handleActivationQueue()  (Now acticvate objects)
31 #       |-> Ogroup selected   
32 #       | |-> Try to adapt values from Ogroup and save directly.
33 #       |
34 #       |-> NO Ogroup selected
35 #       |  |-> Open dialogs of the target object and allow modifcation.
36 #       |
37 #       |->activate_new_device()   (Now activate the device)
38 #
39 #
40 #
41 #
42 #
43 #
44 #
54 class systemManagement extends management
55 {
56   var $plHeadline     = "Systems";
57   var $plDescription  = "List of systems";
58   var $plIcon  = "plugins/systems/images/plugin.png";
60   // Tab definition 
61   protected $tabClass = "";
62   protected $tabType = "";
63   protected $aclCategory = "";
64   protected $aclPlugin   = "";
65   protected $objectName   = "";
67   protected $objectInfo = array();
69   protected $opsi = NULL;
72   protected $activationQueue  = array();
73   
74   function __construct($config,$ui)
75   {
76     $this->config = $config;
77     $this->ui = $ui;
79     // Set storage points 
80     $tD = $this->getObjectDefinitions(); 
81     $sP = array();
82     foreach($tD as $entry){
83       if(!empty($entry['ou']))
84         $sP[] = $entry['ou'];
85     }
86     $this->storagePoints = array_unique($sP);
88     // Build filter
89 #    if (session::global_is_set(get_class($this)."_filter")){
90 #      $filter= session::global_get(get_class($this)."_filter");
91 #    } else {
92       $filter = new filter(get_template_path("system-filter.xml", true));
93       $filter->setObjectStorage($this->storagePoints);
94 #    }
95     $this->setFilter($filter);
97     // Build headpage
98     $headpage = new listing(get_template_path("system-list.xml", true));
99     $headpage->setFilter($filter);
100     $filter->setConverter('INCOMING', 'systemManagement::incomingFilterConverter');
102     // Register Daemon Events
103     if(class_available("DaemonEvent") && class_available("gosaSupportDaemon")){
104       $events = DaemonEvent::get_event_types(SYSTEM_EVENT | HIDDEN_EVENT);
105       foreach($events['TRIGGERED'] as $name => $data){
106         $this->registerAction("T_".$name,"handleEvent");
107         $this->registerAction("S_".$name,"handleEvent");
108       }
109       $this->registerAction("activateMultiple","activateMultiple");
110     }
111     $this->registerAction("saveEvent","saveEventDialog");
112     $this->registerAction("createISO","createISO");
113     $this->registerAction("initiateISOcreation","initiateISOcreation");
114     $this->registerAction("performIsoCreation","performIsoCreation");
115     $this->registerAction("systemTypeChosen","systemTypeChosen");
116     $this->registerAction("handleActivationQueue","handleActivationQueue");
118     $this->registerAction("new_goServer",         "newEntry");
119     $this->registerAction("new_gotoWorkstation",  "newEntry");
120     $this->registerAction("new_gotoTerminal",     "newEntry");
121     $this->registerAction("new_gotoPrinter",      "newEntry");
122     $this->registerAction("new_goFonHardware",    "newEntry");
123     $this->registerAction("new_ieee802Device",    "newEntry");
124     $this->registerAction("new_FAKE_OC_OpsiHost", "newEntry");
126     $this->registerAction("setPassword", "setPassword");
127     $this->registerAction("passwordChangeConfirmed", "passwordChangeConfirmed");
129     // Add copy&paste and snapshot handler.
130     if ($this->config->boolValueIsTrue("main", "copyPaste")){
131       $this->cpHandler = new CopyPasteHandler($this->config);
132     }
133     if($this->config->get_cfg_value("enableSnapshots") == "true"){
134       $this->snapHandler = new SnapshotHandler($this->config);
135     }
137     // Check if we are able to communicate with the GOsa supprot daemon
138     if(class_available("gosaSupportDaemon")){
139       $o = new gosaSupportDaemon();
140       $this->si_active = $o->connect() && class_available("DaemonEvent");
141     }
143     // Check if we are able to communicate with the GOsa supprot daemon
144     if(class_available("opsi")){
145       $this->opsi = new opsi($this->config);
146     }
149     parent::__construct($config, $ui, "systems", $headpage);
150   }
153   function setPassword($action,$target)
154   {
155     if(count($target) == 1){
156       $tDefs= $this->getObjectDefinitions();
157       $headpage = $this->getHeadpage();
158       $dn = array_pop($target);
159       $type = $headpage->getType($dn);
160       $entry = $headpage->getEntry($dn);
161       $ui       = get_userinfo();
162       $smarty = get_smarty();
163       if(in_array("FAKE_OC_PWD_changeAble", $entry['objectClass'])){
164         $acl = $tDefs[$type]['aclCategory'].'/'.$tDefs[$type]['aclClass'];
165         $tabacl   = $ui->get_permissions($dn,$acl,"userPassword");
166         if(preg_match("/w/",$tabacl)){
167           $this->dn= $dn;
168           set_object_info($this->dn);
169           return ($smarty->fetch(get_template_path('password.tpl', TRUE)));
170         }else{
171           msg_dialog::display(_("Permission error"), _("You have no permission to change this password!"), ERROR_DIALOG);
172         }
173       }
174     }
175   }
178   function passwordChangeConfirmed()
179   {
180     $tDefs= $this->getObjectDefinitions();
181     $headpage = $this->getHeadpage();
182     $type = $headpage->getType($this->dn);
183     $entry = $headpage->getEntry($this->dn);
184     $ui       = get_userinfo();
185     $smarty = get_smarty();
187     if(!in_array('FAKE_OC_PWD_changeAble', $entry['objectClass'])){
188       trigger_error("Tried to change pwd, for invalid object!");
189     }elseif ($_POST['new_password'] != $_POST['repeated_password']){
190       msg_dialog::display(_("Error"), 
191           _("The passwords you've entered as 'New password' and 'Repeated password' do not   match!"), ERROR_DIALOG);
192       return($smarty->fetch(get_template_path('password.tpl', TRUE)));
193     }else{
194       $acl = $tDefs[$type]['aclCategory'].'/'.$tDefs[$type]['aclClass'];
195       $tabacl   = $ui->get_permissions($this->dn,$acl,"userPassword");
197       // Check acls
198       if(!preg_match("/w/",$tabacl)){
199         msg_dialog::display(_("Permission error"), _("You have no permission to change this password!"), ERROR_DIALOG);
200       }else{
201         $ldap = $this->config->get_ldap_link();
202         $ldap->cd($this->dn);
203         $ldap->cat($this->dn);
204         $old_attrs = $ldap->fetch();
206         $attrs= array();
207         if ($_POST['new_password'] == ""){
209           /* Remove password attribute
210            */
211           if(in_array("simpleSecurityObject",$old_attrs['objectClass'])){
212             $attrs['objectClass'] = array();
213             for($i = 0 ; $i < $old_attrs['objectClass']['count'] ; $i ++){
214               if(!preg_match("/simpleSecurityObject/i",$old_attrs['objectClass'][$i])){
215                 $attrs['objectClass'][] = $old_attrs['objectClass'][$i];
216               }
217             }
218           }
219           $attrs['userPassword']= array();
220         } else {
222           /* Add/modify password attribute
223            */
224           if(!in_array("simpleSecurityObject",$old_attrs['objectClass'])){
225             $attrs['objectClass'] = array();
226             for($i = 0 ; $i < $old_attrs['objectClass']['count'] ; $i ++){
227               $attrs['objectClass'][] = $old_attrs['objectClass'][$i];
228             }
229             $attrs['objectClass'][] = "simpleSecurityObject";
230           }
232           if(class_available("passwordMethodCrypt")){
233             $pwd_m = new passwordMethodCrypt($this->config);
234             $pwd_m->set_hash("crypt/md5");
235             $attrs['userPassword'] = $pwd_m->generate_hash($_POST['new_password']);
236           }else{
237             msg_dialog::display(_("Password method"),_("Password method crypt is missing. Cannot set system password."));
238             $attrs = array();
239           }
240         }
241         $ldap->modify($attrs);
242         if (!$ldap->success()){
243           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, $type));
244         }else{
245           if(class_available($tDefs[$type]['plugClass'])){
246             $plug = $tDefs[$type]['plugClass'];
247             $p = new $plug($this->config,$this->dn);
248             $p->handle_post_events("modify");
249           }
250         }
251         new log("security","systems/".get_class($this),$this->dn,array_keys($attrs),$ldap->get_error());
252       }
253       set_object_info();
254     }
255   }
258   function createISO($action,$target)
259   {
260     if(count($target) == 1){
261       $smarty = get_smarty();
262       $this->dn= array_pop($target);
263       set_object_info($this->dn);
264       return ($smarty->fetch(get_template_path('goto/gencd.tpl', TRUE)));
266     }
267   }
268   
269   function initiateISOcreation()
270   {
271     $smarty = get_smarty();
272     $smarty->assign("src", "?plug=".$_GET['plug']."&amp;PerformIsoCreation");
273     return ($smarty->fetch(get_template_path('goto/gencd_frame.tpl', TRUE)));  
274   }
277   function performIsoCreation()
278   {
279     $return_button   = "<form method='get' action='main.php' target='_parent'>
280       <input type='submit' value='"._("Back")."'>
281       <input type='hidden' name='plug' value='".$_GET['plug']."'/>
282       </form>";
284     $dsc   = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
286     /* Get and check command */
287     $command= $this->config->search("workgeneric", "SYSTEMISOHOOK",array('tabs'));
288     if (check_command($command)){
289       @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execute");
291       /* Print out html introduction */
292       echo '  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
293         <html>
294         <head>
295         <title></title>
296         <style type="text/css">@import url("themes/default/style.css");</style>
297         <script language="javascript" src="include/focus.js" type="text/javascript"></script>
298         </head>
299         <body style="background: none; margin:4px;" id="body" >
300         <pre>';
302       /* Open process handle and check if it is a valid process */
303       $process= proc_open($command." '".$this->dn."'", $dsc, $pipes);
304       if (is_resource($process)) {
305         fclose($pipes[0]);
307         /* Print out returned lines && write JS to scroll down each line */
308         while (!feof($pipes[1])){
309           $cur_dat = fgets($pipes[1], 1024);
310           echo $cur_dat;
311           echo '<script language="javascript" type="text/javascript">scrollDown2();</script>' ;
312           flush();
313         }
314       }
316       /* Get error string && close streams */
317       $buffer= stream_get_contents($pipes[2]);
319       fclose($pipes[1]);
320       fclose($pipes[2]);
321       echo "</pre>";
323       /* Check return code */
324       $ret= proc_close($process);
325       if ($ret != 0){
326         echo "<h1 style='color:red'>"._("Creating the image failed. Please see the report below.")."</h1>";
327         echo "<pre style='color:red'>$buffer</pre>";
328       }
329       echo $return_button."<br>";
330     } else {
331       $tmp= "<h1 style='color:red'>".sprintf(_("Command '%s', specified for ISO creation doesn't seem to exist."), $command)."</h1>";
332       echo $tmp;
333       echo $return_button."<br>";
334     }
336     /* Scroll down completly */
337     echo '<script language="javascript" type="text/javascript">scrollDown2();</script>' ;
338     echo '</body></html>';
339     flush();
340     exit;
341   }
344   /*! \brief    Handle GOsa-si events
345    *            All events are handled here.
346    */
347   function handleEvent($action="",$target=array(),$all=array())
348   {
349     // Detect whether this event is scheduled or triggered.
350     $triggered = TRUE;
351     if(preg_match("/^S_/",$action)){
352       $triggered = FALSE;
353     }
355     // Detect triggere or scheduled actions 
356     $headpage = $this->getHeadpage();
357     if(preg_match("/^[TS]_/", $action)){
359       // Send special reinstall action for opsi hosts
360       $event = preg_replace("/^[TS]_/","",$action); 
361       if($event == "DaemonEvent_reinstall" && $this->si_active && $this->opsi){
362         foreach($target as $key => $dn){
363           $type = $headpage->getType($dn);
365           // Send Reinstall event for opsi hosts
366           if($type == "FAKE_OC_OpsiHost"){
367             $obj = $headpage->getEntry($dn);
368             $this->opsi->job_opsi_install_client($obj['cn'][0],$obj['macAddress'][0]);
369             unset($target[$key]);
370           }
371         }
372       }
373     } 
375     // Now send remaining FAI/GOsa-si events here.
376     if(count($target) && $this->si_active){
377       $mac= array();
379       // Collect target mac addresses
380       $ldap = $this->config->get_ldap_link();
381       $tD = $this->getObjectDefinitions();
382       $events = DaemonEvent::get_event_types(SYSTEM_EVENT);
383       $o_queue = new gosaSupportDaemon();
384       foreach($target as $dn){
385         $type = $headpage->getType($dn);
386         if($tD[$type]['sendEvents']){
387           $obj = $headpage->getEntry($dn);
388           if(isset($obj['macAddress'][0])){
389             $mac[] = $obj['macAddress'][0];
390           }
391         }
392       }
394       /* Skip installation or update trigerred events,
395        *  if this entry is currently processing.
396        */
397       if($triggered && in_array($event,array("DaemonEvent_reinstall","DaemonEvent_update"))){
398         foreach($mac as $key => $mac_address){
399           foreach($o_queue->get_entries_by_mac(array($mac_address)) as $entry){
400             $entry['STATUS'] = strtoupper($entry['STATUS']);
401             if($entry['STATUS'] == "PROCESSING" &&
402                 isset($events['QUEUED'][$entry['HEADERTAG']]) &&
403                 in_array($events['QUEUED'][$entry['HEADERTAG']],array("DaemonEvent_reinstall","DaemonEvent_update"))){
404               unset($mac[$key]);
406               new log("security","systems/".get_class($this),"",array(),"Skip adding 'DaemonEvent::".$type."' for mac '".$mac_address."', there is already a job in progress.");
407               break;
408             }
409           }
410         }
411       }
413       // Prepare event to be added
414       if(count($mac) && isset($events['BY_CLASS'][$event]) && $this->si_active){
415         $event = $events['BY_CLASS'][$event];
416         $this->dialogObject = new $event['CLASS_NAME']($this->config);
417         $this->dialogObject->add_targets($mac);
419         if($triggered){
420           $this->dialogObject->set_type(TRIGGERED_EVENT);
421           $o_queue->append($this->dialogObject);
422           if($o_queue->is_error()){
423             msg_dialog::display(_("Service infrastructure"),msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
424           }else{
425             $this->closeDialogs();
426           }
427         }else{
428           $this->dialogObject->set_type(SCHEDULED_EVENT);
429         }
430       }
431     }
432   }
434   function cancelEdit()
435   {
436     management::cancelEdit();
437     $this->activationQueue = array();
438   }
439   
440   
441   function saveEventDialog()
442   {
443     $o_queue = new gosaSupportDaemon();
444     $o_queue->append($this->dialogObject);
445     if($o_queue->is_error()){
446       msg_dialog::display(_("Service infrastructure"),msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
447     }else{
448       $this->closeDialogs();
449     }
450  
451   }
452  
454   /*! \brief    Update filter part for INCOMING.
455    *            Allows us to search for "systemIncomingRDN".
456    */
457   static function incomingFilterConverter($filter)
458   {
459     $rdn = preg_replace("/^[^=]*=/", "", get_ou('systemIncomingRDN'));
460     $rdn = preg_replace("/,.*$/","",$rdn);
461     return(preg_replace("/%systemIncomingRDN/", $rdn,$filter));
462   }
464  
465   /*! \brief    Queue selected objects to be removed. 
466    *            Checks ACLs, Locks and ask for confirmation.
467    */
468   protected function removeEntryRequested($action="",$target=array(),$all=array())
469   {
470     $disallowed = array();
471     $this->dns = array();
473     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$target,"Entry removel requested!");
475     // Check permissons for each target
476     $tInfo = $this->getObjectDefinitions();
477     $headpage = $this->getHeadpage();
478     foreach($target as $dn){
479       $type = $headpage->getType($dn);
480       if(!isset($tInfo[$type])){
481         trigger_error("Unknown object type received '".$type."' please update systemManagement::getObjectDefinitions()!");
482       }else{
483         $info = $tInfo[$type];
484         $acl = $this->ui->get_permissions($dn, $info['aclCategory']."/".$info['aclClass']);
485         if(preg_match("/d/",$acl)){
486           $this->dns[] = $dn;
487         }else{
488           $disallowed[] = $dn;
489         }
490       }
491     }
492     if(count($disallowed)){
493       msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
494     }
496     // We've at least one entry to delete.
497     if(count($this->dns)){
499       // check locks
500       if ($user= get_multiple_locks($this->dns)){
501         return(gen_locked_message($user,$this->dns));
502       }
504       // Add locks
505       $dns_names = array();
506       foreach($this->dns as $dn){
507         $dns_names[] =LDAP::fix($dn);
508       }
509       add_lock ($this->dns, $this->ui->dn);
511       // Display confirmation dialog.
512       $smarty = get_smarty();
513       $smarty->assign("info", msgPool::deleteInfo($dns_names,_($this->objectName)));
514       $smarty->assign("multiple", true);
515       return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
516     }
517   }
520   /*! \brief  Object removal was confirmed, now remove the requested entries.
521    *
522    *  @param  String  'action'  The name of the action which was the used as trigger.
523    *  @param  Array   'target'  A list of object dns, which should be affected by this method.
524    *  @param  Array   'all'     A combination of both 'action' and 'target'.
525    */
526   function removeEntryConfirmed($action="",$target=array(),$all=array(),
527       $altTabClass="",$altTabType="",$altAclCategory="")
528   {
529     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$target,"Entry removel confirmed!");
531     // Check permissons for each target
532     $tInfo = $this->getObjectDefinitions();
533     $headpage = $this->getHeadpage();
534     $disallowed = array();
535     foreach($this->dns as $key => $dn){
536       $type = $headpage->getType($dn);
537       if(!isset($tInfo[$type])){
538         trigger_error("Unknown object type received '".$type."' please update systemManagement::getObjectDefinitions()!");
539       }else{
541         $info = $tInfo[$type];
542         $acl = $this->ui->get_permissions($dn, $info['aclCategory']."/".$info['aclClass']);
543         if(preg_match("/d/",$acl)){
545           // Delete the object
546           $this->dn = $dn;
547           $this->tabObject= new $info['tabClass']($this->config,$this->config->data['TABS'][$info['tabDesc']], 
548               $this->dn, $info['aclCategory'], true, true);
549           $this->tabObject->set_acl_base($this->dn);
550           $this->tabObject->parent = &$this;
551           $this->tabObject->delete ();
553           // Remove the lock for the current object.
554           del_lock($this->dn);
556         }else{
557           $disallowed[] = $dn;
558           new log("security","system/".get_class($this),$dn,array(),"Tried to trick deletion.");
559         }
560       }
561     }
562     if(count($disallowed)){
563       msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
564     }
566     // Cleanup
567     $this->remove_lock();
568     $this->closeDialogs();
569   }
572   /*! \brief  Edit the selected system type.
573    *
574    *  @param  String  'action'  The name of the action which was the used as trigger.
575    *  @param  Array   'target'  A list of object dns, which should be affected by this method.
576    *  @param  Array   'all'     A combination of both 'action' and 'target'.
577    */
578   function editEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
579   {
580     if(count($target) == 1){
581       $tInfo = $this->getObjectDefinitions();
582       $headpage = $this->getHeadpage();
583       $dn = $target[0];
584       $type =$headpage->getType($dn);
585       $tData = $tInfo[$type];
587       if($type == "FAKE_OC_ArpNewDevice"){
588         if(!class_available("ArpNewDeviceTabs")){
589           msg_dialog::display(_("Error"), msgPool::class_not_found("ArpNewDevice"), ERROR_DIALOG);
590         }else{
591           return(management::editEntry($action,$target,$all,"ArpNewDeviceTabs","ARPNEWDEVICETABS","incoming"));
592         }
593       }elseif($type == "FAKE_OC_NewDevice"){
594         if(!class_available("SelectDeviceType")){
595           msg_dialog::display(_("Error"), msgPool::class_not_found("SelectDeviceType"), ERROR_DIALOG);
596         }else{
597           $this->activationQueue[$dn] = array();
598           $this->dialogObject = new SelectDeviceType($this->config,$dn);
599           $this->skipFooter = TRUE;
600           $this->displayApplyBtn = FALSE;
601           // see condition  -$s_action == "::systemTypeChosen"-  for further handling
602         }
603       }else{
604          return(management::editEntry($action,$target,$all,$tData['tabClass'],$tData['tabDesc'],$tData['aclCategory']));
605       }
606     }
607   }
610   /*! \brief  Edit the selected system type.
611    *
612    *  @param  String  'action'  The name of the action which was the used as trigger.
613    *  @param  Array   'target'  A list of object dns, which should be affected by this method.
614    *  @param  Array   'all'     A combination of both 'action' and 'target'.
615    */
616   function newEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
617   {
618     $tInfo = $this->getObjectDefinitions();
619     $info = preg_replace("/^new_/","",$action);
620     if(!isset($tInfo[$info])){
621       trigger_error("Unknown action type '".$action."' cant create a new system!");
622     }else{
623       management::newEntry($action,$target,$all, 
624           $tInfo[$info]['tabClass'],
625           $tInfo[$info]['tabDesc'],
626           $tInfo[$info]['aclCategory']);
627     }
628   }
631   function activateMultiple($action,$target)
632   {
633     $headpage = $this->getHeadpage();
634     foreach($target as $dn) {
635       if($headpage->getType($dn) == "FAKE_OC_NewDevice"){
636         $this->activationQueue[$dn] = array();
637       }
638     }
639     if(count($this->activationQueue)){
640       $this->dialogObject = new SelectDeviceType($this->config, array_keys($this->activationQueue));
641       $this->skipFooter = TRUE;
642     }
643   }
648   function systemTypeChosen()
649   {
650     // Detect the systems target type 
651     $tInfo = $this->getObjectDefinitions();
652     $selected_group = "none";
653     if(isset($_POST['ObjectGroup'])){
654       $selected_group = $_POST['ObjectGroup'];
655     }
656     $selected_system = $_POST['SystemType'];
657     $tmp = array();
658     foreach($this->activationQueue as $dn => $data){
659       $tmp[$dn]['OG'] = $selected_group;
660       $tmp[$dn]['SS'] = $selected_system;
661     }
662     $this->closeDialogs();
663     $this->activationQueue = $tmp;
664     return($this->handleActivationQueue());
665   }
668   function handleActivationQueue()
669   {
670     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
671         'Entries left: '.count($this->activationQueue), "<b>Handling system activation queue!</b>");
673     if(!count($this->activationQueue)) return("");
675     $ldap     = $this->config->get_ldap_link();
676     $pInfo    = $this->getObjectDefinitions(); 
677     $ui       = get_userinfo();
678     $headpage = $this->getHeadpage();
679     $ldap->cd($this->config->current['BASE']);
681     // Walk through systems to activate
682     while(count($this->activationQueue)){
683  
684       // Get next entry 
685       reset($this->activationQueue);
686       $dn = key($this->activationQueue);
687       $data= $this->activationQueue[$dn];
689       // Validate the given system type.
690       if(!isset($data['SS'])) continue;
691       $sysType = $data['SS'];
692       if(!isset($pInfo[$sysType])){
693         trigger_error('Unknown type \''.$sysType.'\'!');
694         continue;
695       }
696       $type = $pInfo[$sysType];
698       @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
699           $dn, "<b>Try to activate:</b>");
701       // Get target type definition 
702       $plugClass    = $type["plugClass"];
703       $tabClass     = $type["tabClass"];
704       $aclCategory  = $type["aclCategory"];
705       $tabDesc      = $type["tabDesc"];
707       if(!class_available($tabClass)){
708         msg_dialog::display(_("Error"), msgPool::class_not_found($tabclass), ERROR_DIALOG);
709         unset($this->activationQueue[$dn]);
710         continue;
711       }else{
713         @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
714             $sysType, "<b>System type:</b>");
716         // Load permissions for selected 'dn' and check if we're allowed to create this 'dn' 
717         $this->dn = $dn;
718         $acls   = $ui->get_permissions($this->dn,$aclCategory."/".$plugClass);
720         // Check permissions
721         if(!preg_match("/c/",$acls)){
722           unset($this->activationQueue[$dn]);
723           msg_dialog::display(_("Error"), msgPool::permCreate(), ERROR_DIALOG);
725           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
726               $acls, "<b>Insufficient permissions!</b>");
727           continue;
728         }else{
730           // Open object an preset some values like the objects base 
731           del_lock($dn);
732           management::editEntry('editEntry',array($dn),array(),$tabClass,$tabDesc, $aclCategory);
733           $this->displayApplyBtn = FALSE;
734           $this->tabObject->set_acl_base($headpage->getBase());
736           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
737               $data['OG'], "<b>Selected ogroup:</b>");
739           if($data['OG'] != "none"){
740             $this->tabObject->base = preg_replace("/^[^,]+,".preg_quote(get_ou('ogroupRDN'), '/')."/i", "", $data['OG']);
741             $this->tabObject->by_object[$plugClass]->base = $this->tabObject->base;
742           } else {
743             $this->tabObject->by_object[$plugClass]->base = $headpage->getBase();
744             $this->tabObject->base = $headpage->getBase();
745           }
747           // Assign some default values for opsi hosts
748           if($this->tabObject instanceOf opsi_tabs){
749             $ldap = $this->config->get_ldap_link();
750             $ldap->cat($dn);
751             $source_attrs = $ldap->fetch();
752             foreach(array("macAddress" => "mac" ,"cn" => "hostId","description" => "description") as $src => $attr){
753               if(isset($source_attrs[$src][0])){
754                 $this->tabObject->by_object['opsiGeneric']->$attr = $source_attrs[$src][0];
755               }
756             }
757             @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
758                 "", "<b>OPSI attributes adapted</b>");
759           }
761           // Queue entry to be activated, when it is saved.
762           if($data['OG'] != "none"){
764             // Set gotoMode to active if there was an ogroup selected.
765             $found = false;
766             foreach(array("workgeneric"=>"active","servgeneric"=>"active","termgeneric"=>"active") as $tab => $value){
767               if(isset($this->tabObject->by_object[$tab]->gotoMode)) {
768                 $found = true;
769                 $this->tabObject->by_object[$tab]->gotoMode = $value;
770                 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
771                     $tab."->gotoMode = {$value}", "<b>Setting gotoMode to: </b>");
772               }
773             }
774             if(!$found){
775               msg_dialog::display(_("Internal error"), _("Cannot set mode to 'active'!"), ERROR_DIALOG);
776             }
778             // Update object group membership
779             $og = new ogroup($this->config,$data['OG']);
780             if($og){
781               $og->AddDelMembership($this->tabObject->dn);
782               $og->save();
783               @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
784                   $og->dn, "<b>Adding system to ogroup</b>");
785             }
787             // Set default system specific attributes
788             foreach (array("workgeneric", "termgeneric") as $cls){
789               if (isset($this->tabObject->by_object[$cls])){
790                 $this->tabObject->by_object[$cls]->set_everything_to_inherited();
791                 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
792                     $og->dn, "<b>Calling {$cls}->set_everything_to_inherited()</b>");
793               }
794             }
796             // Enable activation
797             foreach (array("servgeneric", "workgeneric", "termgeneric") as $cls){
798               if (isset($this->tabObject->by_object[$cls])){
799                 $this->tabObject->by_object[$cls]->auto_activate= TRUE;
800                 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
801                     $cls, "<b>Setting auto_activate=TRUE for</b>");
802               }
803             }
805             // Enable sending of LDAP events
806             if (isset($this->tabObject->by_object["workstartup"])){
807               $this->tabObject->by_object["workstartup"]->gotoLdap_inherit= TRUE;
808               @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
809                   "", "<b>Setting workstartup->gotoLdap_inherit=TRUE</b>");
810             }
811           }
813           // Try to inherit everythin from the selected object group and then save
814           //  the entry, normally this should work without any problems. 
815           // But if there is any, then display the dialogs.
816           if($data['OG'] != "none"){
817             $str = $this->saveChanges();
819             // There was a problem, skip activation here and allow to fix the problems..
820             if(is_object($this->tabObject)){
821               @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
822                   "", "<b>Automatic saving failed, let the user fix the issues now.</b>");
823               return;
824             }
825             @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
826                 "", "<b>System activated!</b>");
827           }else{
828             @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
829                 "", "<b>Open dialogs now</b>");
830             return;
831           }
832         }
833       }
834     }
835   }
838   protected function saveChanges()
839   {
840     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
841         get_class($this->tabObject).": ".$this->tabObject->dn, "<b>Save</b>");
842  
843     // Handle 'New Unknown Devices' here.
844     if($this->tabObject instanceOf ArpNewDeviceTabs){
845       $this->tabObject->save_object();
847       if($this->tabObject->by_object['ArpNewDevice']->gotoIntegration){
848         $message = $this->tabObject->check();
849         if(count($message)){
850           msg_dialog::displayChecks($message);
851         }else{
852           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
853               get_class($this->tabObject).": ".$this->tabObject->dn, "<b>Queued for goto activation</b>");
854           $this->tabObject->save();
855           $this->activationQueue[$this->tabObject->dn]=array();
856           $this->closeDialogs();
857           $this->systemTypeChosen();
858         }
859         return;
860       }
861     }
863     //
864     $str = management::saveChanges();
865     if($this->tabObject) return("");
867     if(isset($this->activationQueue[$this->last_dn])){
868       $dn = $this->last_tabObject->dn;
869       $this->activate_new_device($dn);
870       unset($this->activationQueue[$this->last_dn]);
871     }
873     /* Post handling for activated systems
874        target opsi -> Remove source.
875        target gosa -> Activate system.
876      */
877     if($this->last_tabObject instanceOf opsi_tabs){
878       $ldap = $this->config->get_ldap_link();
879       $ldap->cd($this->config->current['BASE']);
880       $ldap->rmdir ($this->last_tabObject->dn);
881       @DEBUG(DEBUG_LDAP,__LINE__, __FUNCTION__, __FILE__,
882           "Source removed: ".$this->tabObject->dn,"<b>Opsi host activated</b>");
884       $hostId =  $this->last_tabObject->by_object['opsiGeneric']->hostId;
885       $mac    =  $this->last_tabObject->by_object['opsiGeneric']->mac;
886       $this->opsi->job_opsi_activate_client($hostId,$mac);
888     }elseif(isset($this->last_tabObject->was_activated) && $this->last_tabObject->was_activated){
889       $this->activate_new_device($this->last_tabObject->dn);
890     }
892     // Avoid using values from an older input dialog
893     $_POST = array();
894     $this->handleActivationQueue();
895   }
898   protected function applyChanges()
899   {
900     $str = management::applyChanges();
901     if($str) return($str);
903     /* Post handling for activated systems
904        target opsi -> Remove source.
905        target gosa -> Activate system.
906      */
907     if($this->tabObject instanceOf opsi_tabs){
908       $ldap = $this->config->get_ldap_link();
909       $ldap->cd($this->config->current['BASE']);
910       $ldap->rmdir ($this->tabObject->dn);
911       @DEBUG(DEBUG_LDAP,__LINE__, __FUNCTION__, __FILE__,
912           "Source removed: ".$this->tabObject->dn,"<b>Opsi host activated</b>");
914       $hostId =  $this->tabObject->by_object['opsiGeneric']->hostId;
915       $mac    =  $this->tabObject->by_object['opsiGeneric']->mac;
916       $this->opsi->job_opsi_activate_client($hostId,$mac);
918     }elseif(isset($this->tabObject->was_activated) && $this->tabObject->was_activated){
919       $this->activate_new_device($this->tabObject->dn);
920     }
921   }
922   
924   /*! \brief  Sets FAIstate to "install" for "New Devices".
925     This function is some kind of "Post handler" for activated systems,
926     it is called directly after the object (workstabs,servtabs) gets saved.
927     @param  String  $dn   The dn of the newly activated object.
928     @return Boolean TRUE if activated else FALSE
929    */
930   function activate_new_device($dn)
931   {
932     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
933         $dn, "<b>Activating system:</b>");
934     $ldap = $this->config->get_ldap_link();
935     $ldap->cd($this->config->current['BASE']);
936     $ldap->cat($dn);
937     if($ldap->count()){
938       $attrs = $ldap->fetch();
939       if(count(array_intersect(array('goServer','gotoWorkstation'), $attrs['objectClass']))){
940         $ocs = $attrs['objectClass'];
941         unset($ocs['count']);
942         $new_attrs = array();
943         if(!in_array("FAIobject",$ocs)){
944           $ocs[] = "FAIobject";
945           $new_attrs['objectClass'] = $ocs;
946         }
947         $new_attrs['FAIstate'] = "install";
948         $ldap->cd($dn);
949         $ldap->modify($new_attrs);
950         if (!$ldap->success()){
951           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn,
952                 LDAP_MOD, "activate_new_device($dn)"));
953           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
954               $dn, "<b>Failed!</b>");
955         }else{
956           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
957               $dn, "<b>Success</b>");
958           return(TRUE);
959         }
960       }else{
961         @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
962             $dn, "<b>FAIstate not set to install, this is only done for gotoWorkstation/goServer!</b>");
963       }
964     }
965     return(FALSE);
966   }
970  /*! \brief  Detects actions/events send by the ui
971    *           and the corresponding targets.
972    */
973   function detectPostActions()
974   {
975     $action= management::detectPostActions();
976     if(isset($_POST['abort_event_dialog']))  $action['action'] = "cancel";
977     if(isset($_POST['save_event_dialog']))  $action['action'] = "saveEvent";
978     if(isset($_POST['cd_create']))  $action['action'] = "initiateISOcreation";
979     if(isset($_GET['PerformIsoCreation']))  $action['action'] = "performIsoCreation";
980     if(isset($_POST['SystemTypeAborted']))  $action['action'] = "cancel";
981     if(isset($_POST['password_cancel']))  $action['action'] = "cancel";
982     if(isset($_POST['password_finish']))  $action['action'] = "passwordChangeConfirmed";
984     if(isset($_POST['new_goServer']))  $action['action'] = "new_goServer";
985     if(isset($_POST['new_gotoWorkstation']))  $action['action'] = "new_gotoWorkstation";
986     if(isset($_POST['new_gotoTerminal']))  $action['action'] = "new_gotoTerminal";
987     if(isset($_POST['new_gotoPrinter']))  $action['action'] = "new_gotoPrinter";
988     if(isset($_POST['new_goFonHardware']))  $action['action'] = "new_goFonHardware";
989     if(isset($_POST['new_ieee802Device']))  $action['action'] = "new_ieee802Device";
990     if(isset($_POST['new_FAKE_OC_OpsiHost']))  $action['action'] = "new_FAKE_OC_OpsiHost";
992     if(!is_object($this->tabObject) && !is_object($this->dialogObject)){
993       if(count($this->activationQueue)) $action['action'] = "handleActivationQueue";
994     }
996     if(isset($_POST['systemTypeChosen']))  $action['action'] = "systemTypeChosen";
998     return($action);
999   }
1002   /*! \brief   Overridden render method of class management.
1003    *            this allows us to add a release selection box.
1004    */
1005   function renderList()
1006   {
1007     $headpage = $this->getHeadpage();
1008     $headpage->update();
1010     $tD = $this->getObjectDefinitions();
1011     $smarty = get_smarty();
1012     foreach($tD as $name => $obj){
1013       $smarty->assign("USE_".$name, (empty($obj['TABNAME']) || class_available($obj['TABNAME'])));
1014     }
1016     $display = $headpage->render();
1017     return($this->getHeader().$display);
1018   }
1021   public function getObjectDefinitions()
1022   {
1023     $tabs = array(
1024         "FAKE_OC_OpsiHost" => array(
1025           "ou"          => "",
1026           "plugClass"   => "opsiGeneric",
1027           "tabClass"    => "opsi_tabs",
1028           "tabDesc"     => "OPSITABS",
1029           "aclClass"    => "opsiGeneric",
1030           "sendEvents"  => TRUE,
1031           "aclCategory" => "opsi"),
1033         "goServer" => array(
1034           "ou"          => get_ou('serverRDN'),
1035           "plugClass"   => "servgeneric",
1036           "tabClass"    => "servtabs",
1037           "tabDesc"     => "SERVTABS",
1038           "aclClass"    => "servgeneric",
1039           "sendEvents"  => TRUE,
1040           "aclCategory" => "server"),
1042         "gotoWorkstation" => array(
1043           "ou"          => get_ou('workstationRDN'),
1044           "plugClass"   => "workgeneric",
1045           "tabClass"    => "worktabs",
1046           "tabDesc"     => "WORKTABS",
1047           "aclClass"    => "workstation",
1048           "sendEvents"  => TRUE,
1049           "aclCategory" => "workgeneric"),
1051         "gotoTerminal" => array(
1052             "ou"          => get_ou('terminalRDN'),
1053             "plugClass"   => "termgeneric",
1054             "tabClass"    => "termtabs",
1055             "sendEvents"  => TRUE,
1056             "tabDesc"     => "TERMTABS",
1057             "aclClass"    => "terminal",
1058             "aclCategory" => "termgeneric"),
1060         "gotoPrinter" => array(
1061             "ou"          => get_ou('printerRDN'),
1062             "plugClass"   => "printgeneric",
1063             "tabClass"    => "printtabs",
1064             "tabDesc"     => "PRINTTABS",
1065             "aclClass"    => "printer",
1066             "sendEvents"  => FALSE,
1067             "aclCategory" => "printgeneric"),
1069         "FAKE_OC_NewDevice" => array(
1070             "ou"          => get_ou('systemIncomingRDN'),
1071             "plugClass"   => "termgeneric",
1072             "tabClass"    => "termtabs",
1073             "sendEvents"  => TRUE,
1074             "tabDesc"     => "TERMTABS",
1075             "aclClass"    => "terminal",
1076             "aclCategory" => "termgeneric"),
1078         "goFonHardware" => array(
1079             "ou"          => get_ou('phoneRDN'),
1080             "plugClass"   => "phoneGeneric",
1081             "tabClass"    => "phonetabs",
1082             "tabDesc"     => "PHONETABS",
1083             "sendEvents"  => FALSE,
1084             "aclClass"    => "phone",
1085             "aclCategory" => "phoneGeneric"),
1087         "FAKE_OC_winstation" => array(
1088             "ou"          => get_winstations_ou(),
1089             "plugClass"   => "wingeneric",
1090             "sendEvents"  => TRUE,
1091             "tabClass"    => "wintabs",
1092             "tabDesc"     => "WINTABS",
1093             "aclClass"    => "wingeneric",
1094             "aclCategory" => "winworkstation"),
1096         "ieee802Device" => array(
1097             "ou"          => get_ou('componentRDN'),
1098             "plugClass"   => "componentGeneric",
1099             "sendEvents"  => FALSE,
1100             "tabClass"    => "componenttabs",
1101             "tabDesc"     => "COMPONENTTABS",
1102             "aclClass"    => "componentGeneric",
1103             "aclCategory" => "component"),
1104         );
1106     // Now map some special types
1107     $tabs['FAKE_OC_NewWorkstation'] = &$tabs['gotoWorkstation'];
1108     $tabs['FAKE_OC_NewTerminal'] = &$tabs['gotoTerminal'];
1109     $tabs['FAKE_OC_NewServer'] = &$tabs['gotoWorkstation'];
1110     $tabs['gotoWorkstation__IS_BUSY'] = &$tabs['gotoWorkstation'];
1111     $tabs['gotoWorkstation__IS_ERROR'] = &$tabs['gotoWorkstation'];
1112     $tabs['gotoWorkstation__IS_LOCKED'] = &$tabs['gotoWorkstation'];
1113     $tabs['gotoTerminal__IS_BUSY'] = &$tabs['gotoTerminal'];
1114     $tabs['gotoTerminal__IS_ERROR'] = &$tabs['gotoTerminal'];
1115     $tabs['gotoTerminal__IS_LOCKED'] = &$tabs['gotoTerminal'];
1116     $tabs['goServer__IS_BUSY'] = &$tabs['goServer'];
1117     $tabs['goServer__IS_ERROR'] = &$tabs['goServer'];
1118     $tabs['goServer__IS_LOCKED'] = &$tabs['goServer'];
1120     $tabs['FAKE_OC_ArpNewDevice'] = &$tabs['FAKE_OC_NewDevice'];
1122     return($tabs);
1123   }
1124
1125 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1126 ?>