Code

Added missing comments
[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 queued 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 system type and allow modifcations.
36 #       |
37 #       |->activate_new_device()   (Finally activate the device - FAIsate=..)
38 #
39 #
40 # NewArpDevices (NewUnknwonDevices )
41 # -> Edit
42 #     |-> editEntry - ArpNewDeviceTabs
43 # -> Save       
44 #     |-> NO gotoIntegeration 
45 #     | |-> Save DHCP and DNS entries, then remove the source entry from ldap.
46 #     |
47 #     |-> gotoIntegration selected (Handle object like a NewDevice now)
48 #     |-> systemTypeChosen()       (Queue entry to be activated)
49 #     |-> handleActivationQueue()  (Now acticvate queued objects)
50 #       |-> Ogroup selected
51 #       | |-> Try to adapt values from ogroup and save directly.
52 #       |
53 #       |-> NO Ogroup selected
54 #       |  |-> Open dialogs of the target system type and allow modifcations.
55 #       |
56 #       |->activate_new_device()   (Finally activate the device - FAIsate=..)
57 #
58 class systemManagement extends management
59 {
60   var $plHeadline     = "Systems";
61   var $plDescription  = "List of systems";
62   var $plIcon  = "plugins/systems/images/plugin.png";
64   // Tab definition 
65   protected $tabClass = "";
66   protected $tabType = "";
67   protected $aclCategory = "";
68   protected $aclPlugin   = "";
69   protected $objectName   = "system";
70   protected $objectInfo = array();
71   protected $opsi = NULL;
72   protected $activationQueue  = array();
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     }
147     parent::__construct($config, $ui, "systems", $headpage);
148   }
151   /*! \brief  Act on password change requests.
152    */
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   /*! \brief  This method is used to queue and process copy&paste actions.
179    *          Allows to copy, cut and paste mutliple entries at once.
180    *  @param  String  'action'  The name of the action which was the used as trigger.
181    *  @param  Array   'target'  A list of object dns, which should be affected by this method.
182    *  @param  Array   'all'     A combination of both 'action' and 'target'.
183    */
184   function copyPasteHandler($action="",$target=array(),$all=array(),
185       $altTabClass ="", $altTabType = "", $altAclCategory="",$altAclPlugin="")
186   {
187     // Return without any actions while copy&paste handler is disabled.
188     if(!is_object($this->cpHandler))  return("");
190     // Save user input
191     $this->cpHandler->save_object();
193     // Add entries to queue
194     if($action == "copy" || $action == "cut"){
196       $tDefs= $this->getObjectDefinitions();
197       $headpage = $this->getHeadpage();
198       $ui       = get_userinfo();
199       $this->cpHandler->cleanup_queue();
200       foreach($target as $dn){
202         $type = $headpage->getType($dn);
203         $entry = $headpage->getEntry($dn);
204   
205         $aclCategory = $tDefs[$type]['aclCategory'];
206         $aclPlugin = $tDefs[$type]['aclClass'];
207         $tabClass = $tDefs[$type]['tabClass'];
208         $tabType = $tDefs[$type]['tabDesc'];
210         if($action == "copy" && $this->ui->is_copyable($dn,$aclCategory,$aclPlugin)){
211           $this->cpHandler->add_to_queue($dn,"copy",$tabClass,$tabType,$aclCategory,$this);
212           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$dn,"Entry copied!");
213         }
214         if($action == "cut" && $this->ui->is_cutable($dn,$aclCategory,$aclPlugin)){
215           $this->cpHandler->add_to_queue($dn,"cut",$tabClass,$tabType,$aclCategory,$this);
216           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$dn,"Entry cutted!");
217         }
218       }
219     }
221     // Initiate pasting
222     if($action == "paste"){
223       $this->cpPastingStarted = TRUE;
224     }
226     // Display any c&p dialogs, eg. object modifications required before pasting.
227     if($this->cpPastingStarted && $this->cpHandler->entries_queued()){
228       $headpage = $this->getHeadpage();
229       $this->cpHandler->SetVar("base",$headpage->getBase());
230       $data = $this->cpHandler->execute();
231       if(!empty($data)){
232         return($data);
233       }
234     }
236     // Automatically disable pasting process since there is no entry left to paste.
237     if(!$this->cpHandler->entries_queued()){
238       $this->cpPastingStarted = FALSE;
239     }
240     return("");
241   }
244   /*! \brief  Password change confirmed, now try to change the systems pwd.
245    */
246   function passwordChangeConfirmed()
247   {
248     $tDefs= $this->getObjectDefinitions();
249     $headpage = $this->getHeadpage();
250     $type = $headpage->getType($this->dn);
251     $entry = $headpage->getEntry($this->dn);
252     $ui       = get_userinfo();
253     $smarty = get_smarty();
255     if(!in_array('FAKE_OC_PWD_changeAble', $entry['objectClass'])){
256       trigger_error("Tried to change pwd, for invalid object!");
257     }elseif ($_POST['new_password'] != $_POST['repeated_password']){
258       msg_dialog::display(_("Error"), 
259           _("The passwords you've entered as 'New password' and 'Repeated password' do not   match!"), ERROR_DIALOG);
260       return($smarty->fetch(get_template_path('password.tpl', TRUE)));
261     }else{
262       $acl = $tDefs[$type]['aclCategory'].'/'.$tDefs[$type]['aclClass'];
263       $tabacl   = $ui->get_permissions($this->dn,$acl,"userPassword");
265       // Check acls
266       if(!preg_match("/w/",$tabacl)){
267         msg_dialog::display(_("Permission error"), _("You have no permission to change this password!"), ERROR_DIALOG);
268       }else{
269         $ldap = $this->config->get_ldap_link();
270         $ldap->cd($this->dn);
271         $ldap->cat($this->dn);
272         $old_attrs = $ldap->fetch();
274         $attrs= array();
275         if ($_POST['new_password'] == ""){
277           /* Remove password attribute
278            */
279           if(in_array("simpleSecurityObject",$old_attrs['objectClass'])){
280             $attrs['objectClass'] = array();
281             for($i = 0 ; $i < $old_attrs['objectClass']['count'] ; $i ++){
282               if(!preg_match("/simpleSecurityObject/i",$old_attrs['objectClass'][$i])){
283                 $attrs['objectClass'][] = $old_attrs['objectClass'][$i];
284               }
285             }
286           }
287           $attrs['userPassword']= array();
288         } else {
290           /* Add/modify password attribute
291            */
292           if(!in_array("simpleSecurityObject",$old_attrs['objectClass'])){
293             $attrs['objectClass'] = array();
294             for($i = 0 ; $i < $old_attrs['objectClass']['count'] ; $i ++){
295               $attrs['objectClass'][] = $old_attrs['objectClass'][$i];
296             }
297             $attrs['objectClass'][] = "simpleSecurityObject";
298           }
300           if(class_available("passwordMethodCrypt")){
301             $pwd_m = new passwordMethodCrypt($this->config);
302             $pwd_m->set_hash("crypt/md5");
303             $attrs['userPassword'] = $pwd_m->generate_hash($_POST['new_password']);
304           }else{
305             msg_dialog::display(_("Password method"),_("Password method crypt is missing. Cannot set system password."));
306             $attrs = array();
307           }
308         }
309         $ldap->modify($attrs);
310         if (!$ldap->success()){
311           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, $type));
312         }else{
313           if(class_available($tDefs[$type]['plugClass'])){
314             $plug = $tDefs[$type]['plugClass'];
315             $p = new $plug($this->config,$this->dn);
316             $p->handle_post_events("modify");
317           }
318         }
319         new log("security","systems/".get_class($this),$this->dn,array_keys($attrs),$ldap->get_error());
320       }
321       set_object_info();
322     }
323   }
326   /*! \brief  The method gets called when somebody clicked the CD icon 
327    *           in the system listing. 
328    *          A confirmation will be shown to acknowledge the creation.
329    */
330   function createISO($action,$target)
331   {
332     if(count($target) == 1){
333       $smarty = get_smarty();
334       $this->dn= array_pop($target);
335       set_object_info($this->dn);
336       return ($smarty->fetch(get_template_path('goto/gencd.tpl', TRUE)));
338     }
339   }
340  
342   /*! \brief  Once the user has confirmed the ISO creation in 'createISO',
343    *           this method gets called. 
344    *          An iFrame is shown which then used 'performIsoCreation' as contents. 
345    */
346   function initiateISOcreation()
347   {
348     $smarty = get_smarty();
349     $smarty->assign("src", "?plug=".$_GET['plug']."&amp;PerformIsoCreation");
350     return ($smarty->fetch(get_template_path('goto/gencd_frame.tpl', TRUE)));  
351   }
354   /*! \brief  ISO creation confirmed and iFrame is visible, now create the ISO 
355    *           and display the status to fill the iFrame.
356    */
357   function performIsoCreation()
358   {
359     $return_button   = "<form method='get' action='main.php' target='_parent'>
360       <input type='submit' value='"._("Back")."'>
361       <input type='hidden' name='plug' value='".$_GET['plug']."'/>
362       </form>";
364     $dsc   = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
366     /* Get and check command */
367     $command= $this->config->search("workgeneric", "SYSTEMISOHOOK",array('tabs'));
368     if (check_command($command)){
369       @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execute");
371       /* Print out html introduction */
372       echo '  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
373         <html>
374         <head>
375         <title></title>
376         <style type="text/css">@import url("themes/default/style.css");</style>
377         <script language="javascript" src="include/focus.js" type="text/javascript"></script>
378         </head>
379         <body style="background: none; margin:4px;" id="body" >
380         <pre>';
382       /* Open process handle and check if it is a valid process */
383       $process= proc_open($command." '".$this->dn."'", $dsc, $pipes);
384       if (is_resource($process)) {
385         fclose($pipes[0]);
387         /* Print out returned lines && write JS to scroll down each line */
388         while (!feof($pipes[1])){
389           $cur_dat = fgets($pipes[1], 1024);
390           echo $cur_dat;
391           echo '<script language="javascript" type="text/javascript">scrollDown2();</script>' ;
392           flush();
393         }
394       }
396       /* Get error string && close streams */
397       $buffer= stream_get_contents($pipes[2]);
399       fclose($pipes[1]);
400       fclose($pipes[2]);
401       echo "</pre>";
403       /* Check return code */
404       $ret= proc_close($process);
405       if ($ret != 0){
406         echo "<h1 style='color:red'>"._("Creating the image failed. Please see the report below.")."</h1>";
407         echo "<pre style='color:red'>$buffer</pre>";
408       }
409       echo $return_button."<br>";
410     } else {
411       $tmp= "<h1 style='color:red'>".sprintf(_("Command '%s', specified for ISO creation doesn't seem to exist."), $command)."</h1>";
412       echo $tmp;
413       echo $return_button."<br>";
414     }
416     /* Scroll down completly */
417     echo '<script language="javascript" type="text/javascript">scrollDown2();</script>' ;
418     echo '</body></html>';
419     flush();
420     exit;
421   }
424   /*! \brief    Handle GOsa-si events
425    *            All schedules and triggered events are handled here.
426    */
427   function handleEvent($action="",$target=array(),$all=array())
428   {
429     // Detect whether this event is scheduled or triggered.
430     $triggered = TRUE;
431     if(preg_match("/^S_/",$action)){
432       $triggered = FALSE;
433     }
435     // Detect triggere or scheduled actions 
436     $headpage = $this->getHeadpage();
437     $event = preg_replace("/^[TS]_/","",$action); 
438     if(preg_match("/^[TS]_/", $action)){
440       // Send special reinstall action for opsi hosts
441       if($event == "DaemonEvent_reinstall" && $this->si_active && $this->opsi){
442         foreach($target as $key => $dn){
443           $type = $headpage->getType($dn);
445           // Send Reinstall event for opsi hosts
446           if($type == "FAKE_OC_OpsiHost"){
447             $obj = $headpage->getEntry($dn);
448             $this->opsi->job_opsi_install_client($obj['cn'][0],$obj['macAddress'][0]);
449             unset($target[$key]);
450           }
451         }
452       }
453     } 
455     // Now send remaining FAI/GOsa-si events here.
456     if(count($target) && $this->si_active){
457       $mac= array();
459       // Collect target mac addresses
460       $ldap = $this->config->get_ldap_link();
461       $tD = $this->getObjectDefinitions();
462       $events = DaemonEvent::get_event_types(SYSTEM_EVENT);
463       $o_queue = new gosaSupportDaemon();
464       foreach($target as $dn){
465         $type = $headpage->getType($dn);
466         if($tD[$type]['sendEvents']){
467           $obj = $headpage->getEntry($dn);
468           if(isset($obj['macAddress'][0])){
469             $mac[] = $obj['macAddress'][0];
470           }
471         }
472       }
474       /* Skip installation or update trigerred events,
475        *  if this entry is currently processing.
476        */
477       if($triggered && in_array($event,array("DaemonEvent_reinstall","DaemonEvent_update"))){
478         foreach($mac as $key => $mac_address){
479           foreach($o_queue->get_entries_by_mac(array($mac_address)) as $entry){
480             $entry['STATUS'] = strtoupper($entry['STATUS']);
481             if($entry['STATUS'] == "PROCESSING" &&
482                 isset($events['QUEUED'][$entry['HEADERTAG']]) &&
483                 in_array($events['QUEUED'][$entry['HEADERTAG']],array("DaemonEvent_reinstall","DaemonEvent_update"))){
484               unset($mac[$key]);
486               new log("security","systems/".get_class($this),"",array(),"Skip adding 'DaemonEvent::".$type."' for mac '".$mac_address."', there is already a job in progress.");
487               break;
488             }
489           }
490         }
491       }
493       // Prepare event to be added
494       if(count($mac) && isset($events['BY_CLASS'][$event]) && $this->si_active){
495         $event = $events['BY_CLASS'][$event];
496         $this->dialogObject = new $event['CLASS_NAME']($this->config);
497         $this->dialogObject->add_targets($mac);
499         if($triggered){
500           $this->dialogObject->set_type(TRIGGERED_EVENT);
501           $o_queue->append($this->dialogObject);
502           if($o_queue->is_error()){
503             msg_dialog::display(_("Service infrastructure"),msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
504           }else{
505             $this->closeDialogs();
506           }
507         }else{
508           $this->dialogObject->set_type(SCHEDULED_EVENT);
509         }
510       }
511     }
512   }
515   /*! \brief  Close all dialogs and reset the activationQueue.
516    */ 
517   function cancelEdit()
518   {
519     management::cancelEdit();
520     $this->activationQueue = array();
521   }
522   
523  
524   /*! \brief  Save event dialogs. 
525    *          And append the new GOsa-si event.
526    */ 
527   function saveEventDialog()
528   {
529     $o_queue = new gosaSupportDaemon();
530     $o_queue->append($this->dialogObject);
531     if($o_queue->is_error()){
532       msg_dialog::display(_("Service infrastructure"),msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
533     }else{
534       $this->closeDialogs();
535     }
536   }
537  
539   /*! \brief    Update filter part for INCOMING.
540    *            Allows us to search for "systemIncomingRDN".
541    */
542   static function incomingFilterConverter($filter)
543   {
544     $rdn = preg_replace("/^[^=]*=/", "", get_ou('systemIncomingRDN'));
545     $rdn = preg_replace("/,.*$/","",$rdn);
546     return(preg_replace("/%systemIncomingRDN/", $rdn,$filter));
547   }
549  
550   /*! \brief    Queue selected objects to be removed. 
551    *            Checks ACLs, Locks and ask for confirmation.
552    */
553   protected function removeEntryRequested($action="",$target=array(),$all=array())
554   {
555     $disallowed = array();
556     $this->dns = array();
558     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$target,"Entry removel requested!");
560     // Check permissons for each target
561     $tInfo = $this->getObjectDefinitions();
562     $headpage = $this->getHeadpage();
563     foreach($target as $dn){
564       $type = $headpage->getType($dn);
565       if(!isset($tInfo[$type])){
566         trigger_error("Unknown object type received '".$type."' please update systemManagement::getObjectDefinitions()!");
567       }else{
568         $info = $tInfo[$type];
569         $acl = $this->ui->get_permissions($dn, $info['aclCategory']."/".$info['aclClass']);
570         if(preg_match("/d/",$acl)){
571           $this->dns[] = $dn;
572         }else{
573           $disallowed[] = $dn;
574         }
575       }
576     }
577     if(count($disallowed)){
578       msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
579     }
581     // We've at least one entry to delete.
582     if(count($this->dns)){
584       // check locks
585       if ($user= get_multiple_locks($this->dns)){
586         return(gen_locked_message($user,$this->dns));
587       }
589       // Add locks
590       $dns_names = array();
591       foreach($this->dns as $dn){
592         $dns_names[] =LDAP::fix($dn);
593       }
594       add_lock ($this->dns, $this->ui->dn);
596       // Display confirmation dialog.
597       $smarty = get_smarty();
598       $smarty->assign("info", msgPool::deleteInfo($dns_names,_($this->objectName)));
599       $smarty->assign("multiple", true);
600       return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
601     }
602   }
605   /*! \brief  Object removal was confirmed, now remove the requested entries.
606    *
607    *  @param  String  'action'  The name of the action which was the used as trigger.
608    *  @param  Array   'target'  A list of object dns, which should be affected by this method.
609    *  @param  Array   'all'     A combination of both 'action' and 'target'.
610    */
611   function removeEntryConfirmed($action="",$target=array(),$all=array(),
612       $altTabClass="",$altTabType="",$altAclCategory="")
613   {
614     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$target,"Entry removel confirmed!");
616     // Check permissons for each target
617     $tInfo = $this->getObjectDefinitions();
618     $headpage = $this->getHeadpage();
619     $disallowed = array();
620     foreach($this->dns as $key => $dn){
621       $type = $headpage->getType($dn);
622       if(!isset($tInfo[$type])){
623         trigger_error("Unknown object type received '".$type."' please update systemManagement::getObjectDefinitions()!");
624       }else{
626         $info = $tInfo[$type];
627         $acl = $this->ui->get_permissions($dn, $info['aclCategory']."/".$info['aclClass']);
628         if(preg_match("/d/",$acl)){
630           // Delete the object
631           $this->dn = $dn;
632           if($info['tabClass'] == "phonetabs"){
633              $this->tabObject= new $tabtype($this->config, $this->config->data['TABS'][$tabobj], $dn,$type);
634              $this->tabObject->set_acl_base($dn);
635              $this->tabObject->by_object['phoneGeneric']->remove_from_parent ();
636           }else{
637             $this->tabObject= new $info['tabClass']($this->config,$this->config->data['TABS'][$info['tabDesc']], 
638                 $this->dn, $info['aclCategory'], true, true);
639             $this->tabObject->set_acl_base($this->dn);
640             $this->tabObject->parent = &$this;
641             $this->tabObject->delete ();
642           }
644           // Remove the lock for the current object.
645           del_lock($this->dn);
647         }else{
648           $disallowed[] = $dn;
649           new log("security","system/".get_class($this),$dn,array(),"Tried to trick deletion.");
650         }
651       }
652     }
653     if(count($disallowed)){
654       msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
655     }
657     // Cleanup
658     $this->remove_lock();
659     $this->closeDialogs();
660   }
663   /*! \brief  Edit the selected system type.
664    *          NewDevice and ArpNewDevice are handled here separately 
665    */
666   function editEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
667   {
668     if(count($target) == 1){
669       $tInfo = $this->getObjectDefinitions();
670       $headpage = $this->getHeadpage();
671       $dn = $target[0];
672       $type =$headpage->getType($dn);
673       $tData = $tInfo[$type];
675       if($type == "FAKE_OC_ArpNewDevice"){
676         if(!class_available("ArpNewDeviceTabs")){
677           msg_dialog::display(_("Error"), msgPool::class_not_found("ArpNewDevice"), ERROR_DIALOG);
678         }else{
679           return(management::editEntry($action,$target,$all,"ArpNewDeviceTabs","ARPNEWDEVICETABS","incoming"));
680         }
681       }elseif($type == "FAKE_OC_NewDevice"){
682         if(!class_available("SelectDeviceType")){
683           msg_dialog::display(_("Error"), msgPool::class_not_found("SelectDeviceType"), ERROR_DIALOG);
684         }else{
685           $this->activationQueue[$dn] = array();
686           $this->dialogObject = new SelectDeviceType($this->config,$dn);
687           $this->skipFooter = TRUE;
688           $this->displayApplyBtn = FALSE;
689           // see condition  -$s_action == "::systemTypeChosen"-  for further handling
690         }
691       }else{
692          return(management::editEntry($action,$target,$all,$tData['tabClass'],$tData['tabDesc'],$tData['aclCategory']));
693       }
694     }
695   }
698   /*! \brief  Edit the selected system type.
699    *
700    *  @param  String  'action'  The name of the action which was the used as trigger.
701    *  @param  Array   'target'  A list of object dns, which should be affected by this method.
702    *  @param  Array   'all'     A combination of both 'action' and 'target'.
703    */
704   function newEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
705   {
706     $tInfo = $this->getObjectDefinitions();
707     $info = preg_replace("/^new_/","",$action);
708     if(!isset($tInfo[$info])){
709       trigger_error("Unknown action type '".$action."' cant create a new system!");
710     }else{
711       management::newEntry($action,$target,$all, 
712           $tInfo[$info]['tabClass'],
713           $tInfo[$info]['tabDesc'],
714           $tInfo[$info]['aclCategory']);
715     }
716   }
719   /*! \brief  Activates all selcted 'NewDevices' at once.
720    *          Enqueues the selected Devices in the activation queue.
721    */
722   function activateMultiple($action,$target)
723   {
724     $headpage = $this->getHeadpage();
725     foreach($target as $dn) {
726       if($headpage->getType($dn) == "FAKE_OC_NewDevice"){
727         $this->activationQueue[$dn] = array();
728       }
729     }
730     if(count($this->activationQueue)){
731       $this->dialogObject = new SelectDeviceType($this->config, array_keys($this->activationQueue));
732       $this->skipFooter = TRUE;
733     }
734   }
737   /*! \brief  The system selection dialog was closed. 
738    *          We will now queue the given entry to be activated.
739    */ 
740   function systemTypeChosen()
741   {
742     // Detect the systems target type 
743     $tInfo = $this->getObjectDefinitions();
744     $selected_group = "none";
745     if(isset($_POST['ObjectGroup'])){
746       $selected_group = $_POST['ObjectGroup'];
747     }
748     $selected_system = $_POST['SystemType'];
749     $tmp = array();
750     foreach($this->activationQueue as $dn => $data){
751       $tmp[$dn]['OG'] = $selected_group;
752       $tmp[$dn]['SS'] = $selected_system;
753     }
754     $this->closeDialogs();
755     $this->activationQueue = $tmp;
756     return($this->handleActivationQueue());
757   }
760   /*! \brief  Activate queued goto systems.
761    */
762   function handleActivationQueue()
763   {
764     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
765         'Entries left: '.count($this->activationQueue), "<b>Handling system activation queue!</b>");
767     if(!count($this->activationQueue)) return("");
769     $ldap     = $this->config->get_ldap_link();
770     $pInfo    = $this->getObjectDefinitions(); 
771     $ui       = get_userinfo();
772     $headpage = $this->getHeadpage();
773     $ldap->cd($this->config->current['BASE']);
775     // Walk through systems to activate
776     while(count($this->activationQueue)){
777  
778       // Get next entry 
779       reset($this->activationQueue);
780       $dn = key($this->activationQueue);
781       $data= $this->activationQueue[$dn];
783       // Validate the given system type.
784       if(!isset($data['SS'])) continue;
785       $sysType = $data['SS'];
786       if(!isset($pInfo[$sysType])){
787         trigger_error('Unknown type \''.$sysType.'\'!');
788         continue;
789       }
790       $type = $pInfo[$sysType];
792       @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
793           $dn, "<b>Try to activate:</b>");
795       // Get target type definition 
796       $plugClass    = $type["plugClass"];
797       $tabClass     = $type["tabClass"];
798       $aclCategory  = $type["aclCategory"];
799       $tabDesc      = $type["tabDesc"];
801       if(!class_available($tabClass)){
802         msg_dialog::display(_("Error"), msgPool::class_not_found($tabclass), ERROR_DIALOG);
803         unset($this->activationQueue[$dn]);
804         continue;
805       }else{
807         @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
808             $sysType, "<b>System type:</b>");
810         // Load permissions for selected 'dn' and check if we're allowed to create this 'dn' 
811         $this->dn = $dn;
812         $acls   = $ui->get_permissions($this->dn,$aclCategory."/".$plugClass);
814         // Check permissions
815         if(!preg_match("/c/",$acls)){
816           unset($this->activationQueue[$dn]);
817           msg_dialog::display(_("Error"), msgPool::permCreate(), ERROR_DIALOG);
819           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
820               $acls, "<b>Insufficient permissions!</b>");
821           continue;
822         }else{
824           // Open object an preset some values like the objects base 
825           del_lock($dn);
826           management::editEntry('editEntry',array($dn),array(),$tabClass,$tabDesc, $aclCategory);
827           $this->displayApplyBtn = FALSE;
828           $this->tabObject->set_acl_base($headpage->getBase());
830           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
831               $data['OG'], "<b>Selected ogroup:</b>");
833           if($data['OG'] != "none"){
834             $this->tabObject->base = preg_replace("/^[^,]+,".preg_quote(get_ou('ogroupRDN'), '/')."/i", "", $data['OG']);
835             $this->tabObject->by_object[$plugClass]->base = $this->tabObject->base;
836           } else {
837             $this->tabObject->by_object[$plugClass]->base = $headpage->getBase();
838             $this->tabObject->base = $headpage->getBase();
839           }
841           // Assign some default values for opsi hosts
842           if($this->tabObject instanceOf opsi_tabs){
843             $ldap = $this->config->get_ldap_link();
844             $ldap->cat($dn);
845             $source_attrs = $ldap->fetch();
846             foreach(array("macAddress" => "mac" ,"cn" => "hostId","description" => "description") as $src => $attr){
847               if(isset($source_attrs[$src][0])){
848                 $this->tabObject->by_object['opsiGeneric']->$attr = $source_attrs[$src][0];
849               }
850             }
851             @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
852                 "", "<b>OPSI attributes adapted</b>");
853           }
855           // Queue entry to be activated, when it is saved.
856           if($data['OG'] != "none"){
858             // Set gotoMode to active if there was an ogroup selected.
859             $found = false;
860             foreach(array("workgeneric"=>"active","servgeneric"=>"active","termgeneric"=>"active") as $tab => $value){
861               if(isset($this->tabObject->by_object[$tab]->gotoMode)) {
862                 $found = true;
863                 $this->tabObject->by_object[$tab]->gotoMode = $value;
864                 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
865                     $tab."->gotoMode = {$value}", "<b>Setting gotoMode to: </b>");
866               }
867             }
868             if(!$found){
869               msg_dialog::display(_("Internal error"), _("Cannot set mode to 'active'!"), ERROR_DIALOG);
870             }
872             // Update object group membership
873             $og = new ogroup($this->config,$data['OG']);
874             if($og){
875               $og->AddDelMembership($this->tabObject->dn);
876               $og->save();
877               @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
878                   $og->dn, "<b>Adding system to ogroup</b>");
879             }
881             // Set default system specific attributes
882             foreach (array("workgeneric", "termgeneric") as $cls){
883               if (isset($this->tabObject->by_object[$cls])){
884                 $this->tabObject->by_object[$cls]->set_everything_to_inherited();
885                 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
886                     $og->dn, "<b>Calling {$cls}->set_everything_to_inherited()</b>");
887               }
888             }
890             // Enable activation
891             foreach (array("servgeneric", "workgeneric", "termgeneric") as $cls){
892               if (isset($this->tabObject->by_object[$cls])){
893                 $this->tabObject->by_object[$cls]->auto_activate= TRUE;
894                 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
895                     $cls, "<b>Setting auto_activate=TRUE for</b>");
896               }
897             }
899             // Enable sending of LDAP events
900             if (isset($this->tabObject->by_object["workstartup"])){
901               $this->tabObject->by_object["workstartup"]->gotoLdap_inherit= TRUE;
902               @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
903                   "", "<b>Setting workstartup->gotoLdap_inherit=TRUE</b>");
904             }
905           }
907           // Try to inherit everythin from the selected object group and then save
908           //  the entry, normally this should work without any problems. 
909           // But if there is any, then display the dialogs.
910           if($data['OG'] != "none"){
911             $str = $this->saveChanges();
913             // There was a problem, skip activation here and allow to fix the problems..
914             if(is_object($this->tabObject)){
915               @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
916                   "", "<b>Automatic saving failed, let the user fix the issues now.</b>");
917               return;
918             }
919             @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
920                 "", "<b>System activated!</b>");
921           }else{
922             @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
923                 "", "<b>Open dialogs now</b>");
924             return;
925           }
926         }
927       }
928     }
929   }
932   /*! \brief  Save object modifications here and any dialogs too.
933    *          After a successfull update of the object data, close
934    *           the dialogs.
935    */
936   protected function saveChanges()
937   {
938     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
939         get_class($this->tabObject).": ".$this->tabObject->dn, "<b>Save</b>");
940  
941     // Handle 'New Unknown Devices' here.
942     if($this->tabObject instanceOf ArpNewDeviceTabs){
943       $this->tabObject->save_object();
945       if($this->tabObject->by_object['ArpNewDevice']->gotoIntegration){
946         $message = $this->tabObject->check();
947         if(count($message)){
948           msg_dialog::displayChecks($message);
949         }else{
950           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
951               get_class($this->tabObject).": ".$this->tabObject->dn, "<b>Queued for goto activation</b>");
952           $this->tabObject->save();
953           $this->activationQueue[$this->tabObject->dn]=array();
954           $this->closeDialogs();
955           $this->systemTypeChosen();
956         }
957         return;
958       }
959     }
961     // Try to save changes here.
962     $str = management::saveChanges();
963     if($this->tabObject) return("");
965     // Activate system if required..
966     if(isset($this->activationQueue[$this->last_dn])){
967       $dn = $this->last_tabObject->dn;
968       $this->activate_new_device($dn);
969       unset($this->activationQueue[$this->last_dn]);
970     }
972     /* Post handling for activated systems
973        target opsi -> Remove source.
974        target gosa -> Activate system.
975      */
976     if($this->last_tabObject instanceOf opsi_tabs){
977       $ldap = $this->config->get_ldap_link();
978       $ldap->cd($this->config->current['BASE']);
979       $ldap->rmdir ($this->last_tabObject->dn);
980       @DEBUG(DEBUG_LDAP,__LINE__, __FUNCTION__, __FILE__,
981           "Source removed: ".$this->tabObject->dn,"<b>Opsi host activated</b>");
983       $hostId =  $this->last_tabObject->by_object['opsiGeneric']->hostId;
984       $mac    =  $this->last_tabObject->by_object['opsiGeneric']->mac;
985       $this->opsi->job_opsi_activate_client($hostId,$mac);
987     }elseif(isset($this->last_tabObject->was_activated) && $this->last_tabObject->was_activated){
988       $this->activate_new_device($this->last_tabObject->dn);
989     }
991     // Avoid using values from an older input dialog
992     $_POST = array();
993     $this->handleActivationQueue();
994   }
997   /*! \brief  Save object modifications here and any dialogs too.
998    *          Keep dialogs opened.
999    */
1000   protected function applyChanges()
1001   {
1002     $str = management::applyChanges();
1003     if($str) return($str);
1005     /* Post handling for activated systems
1006        target opsi -> Remove source.
1007        target gosa -> Activate system.
1008      */
1009     if($this->tabObject instanceOf opsi_tabs){
1010       $ldap = $this->config->get_ldap_link();
1011       $ldap->cd($this->config->current['BASE']);
1012       $ldap->rmdir ($this->tabObject->dn);
1013       @DEBUG(DEBUG_LDAP,__LINE__, __FUNCTION__, __FILE__,
1014           "Source removed: ".$this->tabObject->dn,"<b>Opsi host activated</b>");
1016       $hostId =  $this->tabObject->by_object['opsiGeneric']->hostId;
1017       $mac    =  $this->tabObject->by_object['opsiGeneric']->mac;
1018       $this->opsi->job_opsi_activate_client($hostId,$mac);
1020     }elseif(isset($this->tabObject->was_activated) && $this->tabObject->was_activated){
1021       $this->activate_new_device($this->tabObject->dn);
1022     }
1023   }
1024   
1026   /*! \brief  Sets FAIstate to "install" for "New Devices".
1027     This function is some kind of "Post handler" for activated systems,
1028     it is called directly after the object (workstabs,servtabs) gets saved.
1029     @param  String  $dn   The dn of the newly activated object.
1030     @return Boolean TRUE if activated else FALSE
1031    */
1032   function activate_new_device($dn)
1033   {
1034     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
1035         $dn, "<b>Activating system:</b>");
1036     $ldap = $this->config->get_ldap_link();
1037     $ldap->cd($this->config->current['BASE']);
1038     $ldap->cat($dn);
1039     if($ldap->count()){
1040       $attrs = $ldap->fetch();
1041       if(count(array_intersect(array('goServer','gotoWorkstation'), $attrs['objectClass']))){
1042         $ocs = $attrs['objectClass'];
1043         unset($ocs['count']);
1044         $new_attrs = array();
1045         if(!in_array("FAIobject",$ocs)){
1046           $ocs[] = "FAIobject";
1047           $new_attrs['objectClass'] = $ocs;
1048         }
1049         $new_attrs['FAIstate'] = "install";
1050         $ldap->cd($dn);
1051         $ldap->modify($new_attrs);
1052         if (!$ldap->success()){
1053           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn,
1054                 LDAP_MOD, "activate_new_device($dn)"));
1055           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
1056               $dn, "<b>Failed!</b>");
1057         }else{
1058           @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
1059               $dn, "<b>Success</b>");
1060           return(TRUE);
1061         }
1062       }else{
1063         @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
1064             $dn, "<b>FAIstate not set to install, this is only done for gotoWorkstation/goServer!</b>");
1065       }
1066     }
1067     return(FALSE);
1068   }
1072  /*! \brief  Detects actions/events send by the ui
1073    *           and the corresponding targets.
1074    */
1075   function detectPostActions()
1076   {
1077     $action= management::detectPostActions();
1078     if(isset($_POST['abort_event_dialog']))  $action['action'] = "cancel";
1079     if(isset($_POST['save_event_dialog']))  $action['action'] = "saveEvent";
1080     if(isset($_POST['cd_create']))  $action['action'] = "initiateISOcreation";
1081     if(isset($_GET['PerformIsoCreation']))  $action['action'] = "performIsoCreation";
1082     if(isset($_POST['SystemTypeAborted']))  $action['action'] = "cancel";
1083     if(isset($_POST['password_cancel']))  $action['action'] = "cancel";
1084     if(isset($_POST['password_finish']))  $action['action'] = "passwordChangeConfirmed";
1086     if(isset($_POST['new_goServer']))  $action['action'] = "new_goServer";
1087     if(isset($_POST['new_gotoWorkstation']))  $action['action'] = "new_gotoWorkstation";
1088     if(isset($_POST['new_gotoTerminal']))  $action['action'] = "new_gotoTerminal";
1089     if(isset($_POST['new_gotoPrinter']))  $action['action'] = "new_gotoPrinter";
1090     if(isset($_POST['new_goFonHardware']))  $action['action'] = "new_goFonHardware";
1091     if(isset($_POST['new_ieee802Device']))  $action['action'] = "new_ieee802Device";
1092     if(isset($_POST['new_FAKE_OC_OpsiHost']))  $action['action'] = "new_FAKE_OC_OpsiHost";
1094     if(!is_object($this->tabObject) && !is_object($this->dialogObject)){
1095       if(count($this->activationQueue)) $action['action'] = "handleActivationQueue";
1096     }
1098     if(isset($_POST['systemTypeChosen']))  $action['action'] = "systemTypeChosen";
1100     return($action);
1101   }
1104   /*! \brief   Overridden render method of class management.
1105    *            this allows us to add a release selection box.
1106    */
1107   function renderList()
1108   {
1109     $headpage = $this->getHeadpage();
1110     $headpage->update();
1112     $tD = $this->getObjectDefinitions();
1113     $smarty = get_smarty();
1114     foreach($tD as $name => $obj){
1115       $smarty->assign("USE_".$name, (empty($obj['TABNAME']) || class_available($obj['TABNAME'])));
1116     }
1118     $display = $headpage->render();
1119     return($this->getHeader().$display);
1120   }
1123   public function getObjectDefinitions()
1124   {
1125     $tabs = array(
1126         "FAKE_OC_OpsiHost" => array(
1127           "ou"          => "",
1128           "plugClass"   => "opsiGeneric",
1129           "tabClass"    => "opsi_tabs",
1130           "tabDesc"     => "OPSITABS",
1131           "aclClass"    => "opsiGeneric",
1132           "sendEvents"  => TRUE,
1133           "aclCategory" => "opsi"),
1135         "goServer" => array(
1136           "ou"          => get_ou('serverRDN'),
1137           "plugClass"   => "servgeneric",
1138           "tabClass"    => "servtabs",
1139           "tabDesc"     => "SERVTABS",
1140           "aclClass"    => "servgeneric",
1141           "sendEvents"  => TRUE,
1142           "aclCategory" => "server"),
1144         "gotoWorkstation" => array(
1145           "ou"          => get_ou('workstationRDN'),
1146           "plugClass"   => "workgeneric",
1147           "tabClass"    => "worktabs",
1148           "tabDesc"     => "WORKTABS",
1149           "aclClass"    => "workstation",
1150           "sendEvents"  => TRUE,
1151           "aclCategory" => "workgeneric"),
1153         "gotoTerminal" => array(
1154             "ou"          => get_ou('terminalRDN'),
1155             "plugClass"   => "termgeneric",
1156             "tabClass"    => "termtabs",
1157             "sendEvents"  => TRUE,
1158             "tabDesc"     => "TERMTABS",
1159             "aclClass"    => "terminal",
1160             "aclCategory" => "termgeneric"),
1162         "gotoPrinter" => array(
1163             "ou"          => get_ou('printerRDN'),
1164             "plugClass"   => "printgeneric",
1165             "tabClass"    => "printtabs",
1166             "tabDesc"     => "PRINTTABS",
1167             "aclClass"    => "printer",
1168             "sendEvents"  => FALSE,
1169             "aclCategory" => "printgeneric"),
1171         "FAKE_OC_NewDevice" => array(
1172             "ou"          => get_ou('systemIncomingRDN'),
1173             "plugClass"   => "termgeneric",
1174             "tabClass"    => "termtabs",
1175             "sendEvents"  => TRUE,
1176             "tabDesc"     => "TERMTABS",
1177             "aclClass"    => "terminal",
1178             "aclCategory" => "termgeneric"),
1180         "goFonHardware" => array(
1181             "ou"          => get_ou('phoneRDN'),
1182             "plugClass"   => "phoneGeneric",
1183             "tabClass"    => "phonetabs",
1184             "tabDesc"     => "PHONETABS",
1185             "sendEvents"  => FALSE,
1186             "aclClass"    => "phone",
1187             "aclCategory" => "phoneGeneric"),
1189         "FAKE_OC_winstation" => array(
1190             "ou"          => get_winstations_ou(),
1191             "plugClass"   => "wingeneric",
1192             "sendEvents"  => TRUE,
1193             "tabClass"    => "wintabs",
1194             "tabDesc"     => "WINTABS",
1195             "aclClass"    => "wingeneric",
1196             "aclCategory" => "winworkstation"),
1198         "ieee802Device" => array(
1199             "ou"          => get_ou('componentRDN'),
1200             "plugClass"   => "componentGeneric",
1201             "sendEvents"  => FALSE,
1202             "tabClass"    => "componenttabs",
1203             "tabDesc"     => "COMPONENTTABS",
1204             "aclClass"    => "componentGeneric",
1205             "aclCategory" => "component"),
1206         );
1208     // Now map some special types
1209     $tabs['FAKE_OC_NewWorkstation'] = &$tabs['gotoWorkstation'];
1210     $tabs['FAKE_OC_NewTerminal'] = &$tabs['gotoTerminal'];
1211     $tabs['FAKE_OC_NewServer'] = &$tabs['gotoWorkstation'];
1212     $tabs['gotoWorkstation__IS_BUSY'] = &$tabs['gotoWorkstation'];
1213     $tabs['gotoWorkstation__IS_ERROR'] = &$tabs['gotoWorkstation'];
1214     $tabs['gotoWorkstation__IS_LOCKED'] = &$tabs['gotoWorkstation'];
1215     $tabs['gotoTerminal__IS_BUSY'] = &$tabs['gotoTerminal'];
1216     $tabs['gotoTerminal__IS_ERROR'] = &$tabs['gotoTerminal'];
1217     $tabs['gotoTerminal__IS_LOCKED'] = &$tabs['gotoTerminal'];
1218     $tabs['goServer__IS_BUSY'] = &$tabs['goServer'];
1219     $tabs['goServer__IS_ERROR'] = &$tabs['goServer'];
1220     $tabs['goServer__IS_LOCKED'] = &$tabs['goServer'];
1222     $tabs['FAKE_OC_ArpNewDevice'] = &$tabs['FAKE_OC_NewDevice'];
1224     return($tabs);
1225   }
1228   /*! \brief  !! Incoming dummy acls, required to defined acls for incoming objects
1229    */
1230   static function plInfo()
1231   {
1232     return (array(
1233           "plShortName"   => _("Incoming objects"),
1234           "plDescription" => _("Incoming objects"),
1235           "plSelfModify"  => FALSE,
1236           "plDepends"     => array(),
1237           "plPriority"    => 99,
1238           "plSection"     => array("administration"),
1239           "plCategory"    => array("incoming"   => array( "description"  => _("Incoming"),
1240               "objectClass"  => "")),
1241           "plProvidedAcls"=> array()
1242           ));
1243   }
1244
1245 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1246 ?>