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