1<?php
2
3/*
4   ------------------------------------------------------------------------
5   FusionInventory
6   Copyright (C) 2010-2016 by the FusionInventory Development Team.
7
8   http://www.fusioninventory.org/   http://forge.fusioninventory.org/
9   ------------------------------------------------------------------------
10
11   LICENSE
12
13   This file is part of FusionInventory project.
14
15   FusionInventory is free software: you can redistribute it and/or modify
16   it under the terms of the GNU Affero General Public License as published by
17   the Free Software Foundation, either version 3 of the License, or
18   (at your option) any later version.
19
20   FusionInventory is distributed in the hope that it will be useful,
21   but WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23   GNU Affero General Public License for more details.
24
25   You should have received a copy of the GNU Affero General Public License
26   along with FusionInventory. If not, see <http://www.gnu.org/licenses/>.
27
28   ------------------------------------------------------------------------
29
30   @package   FusionInventory
31   @author    Vincent Mazzoni
32   @co-author David Durieux
33   @copyright Copyright (c) 2010-2016 FusionInventory team
34   @license   AGPL License 3.0 or (at your option) any later version
35              http://www.gnu.org/licenses/agpl-3.0-standalone.html
36   @link      http://www.fusioninventory.org/
37   @link      http://forge.fusioninventory.org/projects/fusioninventory-for-glpi/
38   @since     2010
39
40   ------------------------------------------------------------------------
41 */
42
43if (!defined('GLPI_ROOT')) {
44   die("Sorry. You can't access this file directly");
45}
46
47class PluginFusioninventoryCommunicationNetworkInventory {
48
49   private $ptd, $logFile, $agent, $arrayinventory;
50   private $a_ports = array();
51
52   static $rightname = 'plugin_fusioninventory_networkequipment';
53
54
55   function __construct() {
56      if (PluginFusioninventoryConfig::isExtradebugActive()) {
57         $this->logFile = GLPI_LOG_DIR.'/fusioninventorycommunication.log';
58      }
59   }
60
61
62
63   /**
64    * Import data
65    *
66    *@param $p_DEVICEID XML code to import
67    *@param $p_CONTENT XML code to import
68    *@return "" (import ok) / error string (import ko)
69    **/
70   function import($p_DEVICEID, $a_CONTENT, $arrayinventory) {
71
72      //$_SESSION['SOURCEXML'] = $p_xml;
73
74      PluginFusioninventoryCommunication::addLog(
75              'Function PluginFusioninventoryCommunicationNetworkInventory->import().');
76
77      $pfAgent = new PluginFusioninventoryAgent();
78      $pfTaskjobstate = new PluginFusioninventoryTaskjobstate();
79
80      $this->agent = $pfAgent->InfosByKey($p_DEVICEID);
81
82      $this->arrayinventory = $arrayinventory;
83
84      $_SESSION['glpi_plugin_fusioninventory_processnumber'] = $a_CONTENT['PROCESSNUMBER'];
85      if ((!isset($a_CONTENT['AGENT']['START'])) AND (!isset($a_CONTENT['AGENT']['END']))) {
86          $nb_devices = 0;
87          if (isset($a_CONTENT['DEVICE'])) {
88              if (is_int(key($a_CONTENT['DEVICE']))) {
89                  $nb_devices = count($a_CONTENT['DEVICE']);
90              } else {
91                  $nb_devices = 1;
92              }
93          }
94
95          $_SESSION['plugin_fusinvsnmp_taskjoblog']['taskjobs_id'] =
96              $a_CONTENT['PROCESSNUMBER'];
97          $_SESSION['plugin_fusinvsnmp_taskjoblog']['items_id'] = $this->agent['id'];
98          $_SESSION['plugin_fusinvsnmp_taskjoblog']['itemtype'] = 'PluginFusioninventoryAgent';
99          $_SESSION['plugin_fusinvsnmp_taskjoblog']['state'] = '6';
100          $_SESSION['plugin_fusinvsnmp_taskjoblog']['comment'] = $nb_devices.
101              ' ==devicesqueried==';
102          $this->addtaskjoblog();
103
104      }
105
106      $this->importContent($a_CONTENT);
107
108      if (isset($a_CONTENT['AGENT']['END'])) {
109         $cnt = countElementsInTable('glpi_plugin_fusioninventory_taskjoblogs',
110                                       "`plugin_fusioninventory_taskjobstates_id`='".$a_CONTENT['PROCESSNUMBER']."' "
111                          . " AND `comment` LIKE '%[==detail==] Update %'");
112
113          $pfTaskjobstate->changeStatusFinish(
114                  $a_CONTENT['PROCESSNUMBER'],
115                  $this->agent['id'],
116                  'PluginFusioninventoryAgent',
117                  '0',
118                  'Total updated:'.$cnt);
119      }
120      if (isset($a_CONTENT['AGENT']['START'])) {
121          $_SESSION['plugin_fusinvsnmp_taskjoblog']['taskjobs_id'] =
122              $a_CONTENT['PROCESSNUMBER'];
123          $_SESSION['plugin_fusinvsnmp_taskjoblog']['items_id'] = $this->agent['id'];
124          $_SESSION['plugin_fusinvsnmp_taskjoblog']['itemtype'] = 'PluginFusioninventoryAgent';
125          $_SESSION['plugin_fusinvsnmp_taskjoblog']['state'] = '6';
126          $_SESSION['plugin_fusinvsnmp_taskjoblog']['comment'] = '==inventorystarted==';
127          $this->addtaskjoblog();
128      }
129   }
130
131
132
133   /**
134    * Import the content (where have all devices)
135    *@param $p_content CONTENT code to import
136    *
137    *@return errors string to be alimented if import ko / '' if ok
138    **/
139   function importContent($arrayinventory) {
140
141      PluginFusioninventoryCommunication::addLog(
142              'Function PluginFusioninventoryCommunicationNetworkInventory->importContent().');
143      $pfAgent = new PluginFusioninventoryAgent();
144
145      $errors='';
146      $nbDevices = 0;
147      foreach ($arrayinventory as $childname=>$child) {
148         PluginFusioninventoryCommunication::addLog($childname);
149         switch ($childname) {
150
151            case 'DEVICE' :
152               $a_devices = array();
153               if (is_int(key($child))) {
154                  $a_devices = $child;
155               } else {
156                  $a_devices[] = $child;
157               }
158               $xml_num = 0;
159               foreach ($a_devices as $dchild) {
160                  $_SESSION['plugin_fusioninventory_xmlnum'] = $xml_num;
161                  $a_inventory = array();
162                  if (isset($dchild['INFO'])) {
163                     if ($dchild['INFO']['TYPE'] == "NETWORKING") {
164                        $a_inventory = PluginFusioninventoryFormatconvert::networkequipmentInventoryTransformation($dchild);
165                     } else if ($dchild['INFO']['TYPE'] == "PRINTER") {
166                        $a_inventory = PluginFusioninventoryFormatconvert::printerInventoryTransformation($dchild);
167                     }
168                  }
169                  if (isset($dchild['ERROR'])) {
170                     $itemtype = "";
171                     if ($dchild['ERROR']['TYPE'] == "NETWORKING") {
172                        $itemtype = "NetworkEquipment";
173                     } else if ($dchild['ERROR']['TYPE'] == "PRINTER") {
174                        $itemtype = "Printer";
175                     }
176                     $_SESSION['plugin_fusinvsnmp_taskjoblog']['comment'] = '[==detail==] '.
177                             $dchild['ERROR']['MESSAGE'].' [['.$itemtype.'::'.
178                             $dchild['ERROR']['ID'].']]';
179                     $this->addtaskjoblog();
180                  } else if ($a_inventory['PluginFusioninventory'.$a_inventory['itemtype']]['sysdescr'] == ''
181                              && $a_inventory[$a_inventory['itemtype']]['name'] == ''
182                              && $a_inventory[$a_inventory['itemtype']]['serial'] == '') {
183
184                     $_SESSION['plugin_fusinvsnmp_taskjoblog']['comment'] =
185                              '[==detail==] No informations [['.$a_inventory['itemtype'].'::'.$dchild['INFO']['ID'].']]';
186                     $this->addtaskjoblog();
187                  } else {
188                     if (count($a_inventory) > 0) {
189                        $errors .= $this->sendCriteria($a_inventory);
190                        $nbDevices++;
191                     }
192                  }
193                  $xml_num++;
194               }
195               break;
196
197            case 'AGENT' :
198               if (isset($this->arrayinventory['CONTENT']['AGENT']['AGENTVERSION'])) {
199                  $agent = $pfAgent->InfosByKey($this->arrayinventory['DEVICEID']);
200                  $agent['fusioninventory_agent_version'] =
201                                       $this->arrayinventory['CONTENT']['AGENT']['AGENTVERSION'];
202                  $agent['last_agent_update'] = date("Y-m-d H:i:s");
203                  $pfAgent->update($agent);
204               }
205               break;
206
207            case 'PROCESSNUMBER' :
208               break;
209
210            case 'MODULEVERSION' :
211               break;
212
213            default :
214               $_SESSION['plugin_fusinvsnmp_taskjoblog']['comment'] = '[==detail==] '.
215                           __('Unattended element in', 'fusioninventory').' CONTENT : '.$childname;
216               $this->addtaskjoblog();
217         }
218      }
219      return $errors;
220   }
221
222
223
224   /**
225    * Import one device
226    *
227    * @param type $itemtype
228    * @param type $items_id
229    *
230    * @return errors string to be alimented if import ko / '' if ok
231    */
232   function importDevice($itemtype, $items_id, $a_inventory) {
233      global $PLUGIN_FUSIONINVENTORY_XML;
234
235      PluginFusioninventoryCommunication::addLog(
236              'Function PluginFusioninventoryCommunicationNetworkInventory->importDevice().');
237
238      $pfFormatconvert = new PluginFusioninventoryFormatconvert();
239      $a_inventory = $pfFormatconvert->replaceids($a_inventory, $itemtype, $items_id);
240
241      // Write XML file
242      if (count($a_inventory) > 0
243              AND isset($_SESSION['plugin_fusioninventory_xmlnum'])) {
244         $xml = $PLUGIN_FUSIONINVENTORY_XML->CONTENT->DEVICE[$_SESSION['plugin_fusioninventory_xmlnum']]->asXML();
245         PluginFusioninventoryToolbox::writeXML(
246                 $items_id,
247                 $xml,
248                 $itemtype);
249       }
250
251      $errors='';
252      $this->deviceId=$items_id;
253
254
255      $serialized = gzcompress(serialize($a_inventory));
256
257      if (isset($a_inventory['name'])
258              && $a_inventory['name'] == '') {
259         unset($a_inventory['name']);
260      }
261      if (isset($a_inventory['serial'])
262              && $a_inventory['serial'] == '') {
263         unset($a_inventory['serial']);
264      }
265
266      switch ($itemtype) {
267
268         case 'Printer':
269            $pfiPrinterLib = new PluginFusioninventoryInventoryPrinterLib();
270            $a_inventory['PluginFusioninventoryPrinter']['serialized_inventory'] =
271                        Toolbox::addslashes_deep($serialized);
272            $pfiPrinterLib->updatePrinter($a_inventory, $items_id);
273            break;
274
275         case 'NetworkEquipment':
276            $pfiNetworkEquipmentLib = new PluginFusioninventoryInventoryNetworkEquipmentLib();
277            $a_inventory['PluginFusioninventoryNetworkEquipment']['serialized_inventory'] =
278                        Toolbox::addslashes_deep($serialized);
279            $pfiNetworkEquipmentLib->updateNetworkEquipment($a_inventory, $items_id);
280            break;
281
282         default:
283            $errors.=__('Unattended element in', 'fusioninventory').' TYPE : '
284                              .$a_inventory['itemtype']."\n";
285      }
286   }
287
288
289
290   /**
291    * Send XML of SNMP device to rules
292    *
293    * @param simplexml $p_CONTENT
294    *
295    * @return type
296    */
297   function sendCriteria($a_inventory) {
298
299      PluginFusioninventoryCommunication::addLog(
300              'Function PluginFusioninventoryCommunicationNetworkInventory->sendCriteria().');
301
302      $errors = '';
303
304      // Manual blacklist
305       if ($a_inventory[$a_inventory['itemtype']]['serial'] == 'null') {
306          $a_inventory[$a_inventory['itemtype']]['serial'] = '';
307       }
308       // End manual blacklist
309
310       $_SESSION['SOURCE_XMLDEVICE'] = $a_inventory;
311       $input = array();
312
313      // Global criterias
314
315         if (!empty($a_inventory[$a_inventory['itemtype']]['serial'])) {
316            $input['serial'] = $a_inventory[$a_inventory['itemtype']]['serial'];
317         }
318         if ($a_inventory['itemtype'] == 'NetworkEquipment') {
319            if (!empty($a_inventory[$a_inventory['itemtype']]['mac'])) {
320               $input['mac'][] = $a_inventory[$a_inventory['itemtype']]['mac'];
321            }
322            $input['itemtype'] = "NetworkEquipment";
323         } else if ($a_inventory['itemtype'] == 'Printer') {
324            $input['itemtype'] = "Printer";
325            if (isset($a_inventory['networkport'])) {
326               $a_ports = array();
327               if (is_int(key($a_inventory['networkport']))) {
328                  $a_ports = $a_inventory['networkport'];
329               } else {
330                  $a_ports[] = $a_inventory['networkport'];
331               }
332               foreach($a_ports as $port) {
333                  if (!empty($port['mac'])) {
334                     $input['mac'][] = $port['mac'];
335                  }
336                  if (!empty($port['ip'])) {
337                     $input['ip'][] = $port['ip'];
338                  }
339               }
340            }
341         }
342         if (!empty($a_inventory[$a_inventory['itemtype']]['networkequipmentmodels_id'])) {
343            $input['model'] = $a_inventory[$a_inventory['itemtype']]['networkequipmentmodels_id'];
344         }
345         if (!empty($a_inventory[$a_inventory['itemtype']]['name'])) {
346            $input['name'] = $a_inventory[$a_inventory['itemtype']]['name'];
347         }
348
349      $_SESSION['plugin_fusinvsnmp_datacriteria'] = serialize($input);
350      $_SESSION['plugin_fusioninventory_classrulepassed'] =
351                                 "PluginFusioninventoryCommunicationNetworkInventory";
352      $rule = new PluginFusioninventoryInventoryRuleImportCollection();
353      PluginFusioninventoryConfig::logIfExtradebug("pluginFusioninventory-rules",
354                                                   "Input data : ".print_r($input, TRUE));
355      $data = $rule->processAllRules($input, array());
356      PluginFusioninventoryConfig::logIfExtradebug("pluginFusioninventory-rules",
357                                                   $data);
358      if (isset($data['action'])
359             && ($data['action'] == PluginFusioninventoryInventoryRuleImport::LINK_RESULT_DENIED)) {
360
361         $a_text = '';
362         foreach ($input as $key=>$data) {
363            if (is_array($data)) {
364               $a_text[] = "[".$key."]:".implode(", ", $data);
365            } else {
366               $a_text[] = "[".$key."]:".$data;
367            }
368         }
369         $_SESSION['plugin_fusinvsnmp_taskjoblog']['comment'] = '==importdenied== '.
370                 implode(", ", $a_text);
371         $this->addtaskjoblog();
372
373         $pfIgnoredimportdevice = new PluginFusioninventoryIgnoredimportdevice();
374         $inputdb = array();
375         if (isset($input['name'])) {
376            $inputdb['name'] = $input['name'];
377         }
378         $inputdb['date'] = date("Y-m-d H:i:s");
379         $inputdb['itemtype'] = $input['itemtype'];
380         if (isset($input['serial'])) {
381            $input['serialnumber'] = $input['serial'];
382         }
383         if (isset($input['ip'])) {
384            $inputdb['ip'] = exportArrayToDB($input['ip']);
385         }
386         if (isset($input['mac'])) {
387            $inputdb['mac'] = exportArrayToDB($input['mac']);
388         }
389         $inputdb['rules_id'] = $_SESSION['plugin_fusioninventory_rules_id'];
390         $inputdb['method'] = 'networkinventory';
391         $pfIgnoredimportdevice->add($inputdb);
392         unset($_SESSION['plugin_fusioninventory_rules_id']);
393      }
394      if (isset($data['_no_rule_matches']) AND ($data['_no_rule_matches'] == '1')) {
395         if (isset($input['itemtype'])
396             && isset($data['action'])
397             && ($data['action'] == PluginFusioninventoryInventoryRuleImport::LINK_RESULT_CREATE)) {
398
399            $errors .= $this->rulepassed(0, $input['itemtype']);
400         } else if (isset($input['itemtype'])
401              AND !isset($data['action'])) {
402            $id_xml = $a_inventory[$a_inventory['itemtype']]['id'];
403            $classname = $input['itemtype'];
404            $class = new $classname;
405            if ($class->getFromDB($id_xml)) {
406               $errors .= $this->rulepassed($id_xml, $input['itemtype']);
407            } else {
408               $errors .= $this->rulepassed(0, $input['itemtype']);
409            }
410         } else {
411            $errors .= $this->rulepassed(0, "PluginFusioninventoryUnmanaged");
412         }
413      }
414      return $errors;
415   }
416
417
418
419   /**
420    * After rules import device
421    *
422    * @param integer $items_id id of the device in GLPI DB (0 = created, other = merge)
423    * @param varchar $itemtype itemtype of the device
424    *
425    * @return type
426    */
427   function rulepassed($items_id, $itemtype) {
428
429      PluginFusioninventoryLogger::logIfExtradebug(
430         "pluginFusioninventory-rules",
431         "Rule passed : ".$items_id.", ".$itemtype."\n"
432      );
433      PluginFusioninventoryLogger::logIfExtradebugAndDebugMode(
434         'fusioninventorycommunication',
435         'Function PluginFusinvsnmpCommunicationSNMPQuery->rulepassed().'
436      );
437
438      $_SESSION["plugin_fusioninventory_entity"] = 0;
439
440      PluginFusioninventoryConfig::logIfExtradebug("pluginFusioninventory-rules",
441                                                   "Rule passed : ".$items_id.", ".$itemtype."\n");
442      PluginFusioninventoryCommunication::addLog(
443              'Function PluginFusioninventoryCommunicationNetworkInventory->rulepassed().');
444
445      $a_inventory = $_SESSION['SOURCE_XMLDEVICE'];
446
447      $errors = '';
448      $class = new $itemtype;
449      if ($items_id == "0") {
450         $input = array();
451         $input['date_mod'] = date("Y-m-d H:i:s");
452         if ($class->getFromDB($a_inventory[$a_inventory['itemtype']]['id'])) {
453            $input['entities_id'] = $class->fields['entities_id'];
454         } else {
455            $input['entities_id'] = 0;
456         }
457         if (!isset($_SESSION['glpiactiveentities_string'])) {
458            $_SESSION['glpiactiveentities_string'] = "'".$input['entities_id']."'";
459         }
460         $_SESSION["plugin_fusioninventory_entity"] = $input['entities_id'];
461         $items_id = $class->add($input);
462         if (isset($_SESSION['plugin_fusioninventory_rules_id'])) {
463            $pfRulematchedlog = new PluginFusioninventoryRulematchedlog();
464            $inputrulelog = array();
465            $inputrulelog['date'] = date('Y-m-d H:i:s');
466            $inputrulelog['rules_id'] = $_SESSION['plugin_fusioninventory_rules_id'];
467            if (isset($_SESSION['plugin_fusioninventory_agents_id'])) {
468               $inputrulelog['plugin_fusioninventory_agents_id'] =
469                                                   $_SESSION['plugin_fusioninventory_agents_id'];
470            }
471            $inputrulelog['items_id'] = $items_id;
472            $inputrulelog['itemtype'] = $itemtype;
473            $inputrulelog['method'] = 'snmpinventory';
474            $pfRulematchedlog->add($inputrulelog);
475            $pfRulematchedlog->cleanOlddata($items_id, $itemtype);
476            unset($_SESSION['plugin_fusioninventory_rules_id']);
477         }
478      }
479      if ($itemtype == "PluginFusioninventoryUnmanaged") {
480         $class->getFromDB($items_id);
481         $input = array();
482         $input['id'] = $class->fields['id'];
483         if (!empty($a_inventory[$a_inventory['itemtype']]['name'])) {
484            $input['name'] = $a_inventory[$a_inventory['itemtype']]['name'];
485         }
486         if (!empty($a_inventory[$a_inventory['itemtype']]['serial'])) {
487            $input['serial'] = $a_inventory[$a_inventory['itemtype']]['serial'];
488         }
489         if (!empty($a_inventory['itemtype'])) {
490            $input['itemtype'] = $a_inventory['itemtype'];
491         }
492         // TODO : add import ports
493         PluginFusioninventoryToolbox::writeXML($items_id,
494                                                serialize($_SESSION['SOURCE_XMLDEVICE']),
495                                                'PluginFusioninventoryUnmanaged');
496         $class->update($input);
497         $_SESSION['plugin_fusinvsnmp_taskjoblog']['comment'] =
498            '[==detail==] ==updatetheitem== Update '.
499                 PluginFusioninventoryUnmanaged::getTypeName().
500                 ' [[PluginFusioninventoryUnmanaged::'.$items_id.']]';
501         $this->addtaskjoblog();
502      } else {
503         $_SESSION['plugin_fusinvsnmp_taskjoblog']['comment'] =
504               '[==detail==] Update '.$class->getTypeName().' [['.$itemtype.'::'.$items_id.']]';
505         $this->addtaskjoblog();
506         $errors .= $this->importDevice($itemtype, $items_id, $a_inventory);
507      }
508      return $errors;
509   }
510
511
512
513   /**
514    * Used to add log in the task
515    */
516   function addtaskjoblog() {
517
518      if (!isset($_SESSION['plugin_fusinvsnmp_taskjoblog']['taskjobs_id'])) {
519         return;
520      }
521
522      $pfTaskjoblog = new PluginFusioninventoryTaskjoblog();
523      $pfTaskjoblog->addTaskjoblog(
524                     $_SESSION['plugin_fusinvsnmp_taskjoblog']['taskjobs_id'],
525                     $_SESSION['plugin_fusinvsnmp_taskjoblog']['items_id'],
526                     $_SESSION['plugin_fusinvsnmp_taskjoblog']['itemtype'],
527                     $_SESSION['plugin_fusinvsnmp_taskjoblog']['state'],
528                     $_SESSION['plugin_fusinvsnmp_taskjoblog']['comment']);
529   }
530
531
532
533   static function getMethod() {
534      return 'snmpinventory';
535   }
536
537}
538
539?>
540