. * --------------------------------------------------------------------- */ /** * Create an abstration layer for any kind of internet label */ if (!defined('GLPI_ROOT')) { die("Sorry. You can't access this file directly"); } /// Class FQDNLabel - any kind of internet label (computer name as well as alias) /// Since version 0.84 abstract class FQDNLabel extends CommonDBChild { // Inherits from CommonDBChild as it must be attached to a specific element // (NetworkName, NetworkPort, ...) function getInternetName() { // get the full computer name of the current object (for instance : forge.indepnet.net) return self::getInternetNameFromLabelAndDomainID($this->fields["name"], $this->fields["fqdns_id"]); } /** * Get the internet name from a label and a domain ID * * @param string $label the label of the computer or its alias * @param integer $domain id of the domain that owns the item * * @return string result the full internet name **/ static function getInternetNameFromLabelAndDomainID($label, $domain) { $domainName = FQDN::getFQDNFromID($domain); if (!empty($domainName)) { return $label.".".$domainName; } return $label; } /** * \brief Check FQDN label * Check a label regarding section 2.1 of RFC 1123 : 63 lengths and no other characters * than alphanumerics. Minus ('-') is allowed if it is not at the end or begin of the lable. * * @param string $label the label to check **/ static function checkFQDNLabel($label) { if (strlen($label) == 1) { if (!preg_match("/^[0-9A-Za-z]$/", $label, $regs)) { return false; } } else { $fqdn_regex = "/^(?!-)[A-Za-z0-9-]{1,63}(?encode($label); if (!preg_match($fqdn_regex, $idn, $regs)) { return false; } } } return true; } /** * @param $input **/ function prepareLabelInput($input) { if (isset($input['name']) && !empty($input['name'])) { // Empty names are allowed $input['name'] = strtolower($input['name']); // Before adding a name, we must unsure its is valid : it conforms to RFC if (!self::checkFQDNLabel($input['name'])) { Session::addMessageAfterRedirect(sprintf(__('Invalid internet name: %s'), $input['name']), false, ERROR); return false; } } return $input; } function prepareInputForAdd($input) { return parent::prepareInputForAdd($this->prepareLabelInput($input)); } function prepareInputForUpdate($input) { return parent::prepareInputForUpdate($this->prepareLabelInput($input)); } /** * Get all label IDs corresponding to given string label and FQDN ID * * @param $label string label to search for * @param $fqdns_id integer the id of the FQDN that owns the label * @param $wildcard_search boolean true if we search with wildcard (false by default) * * @return array two arrays (NetworkName and NetworkAlias) of the IDs **/ static function getIDsByLabelAndFQDNID($label, $fqdns_id, $wildcard_search = false) { global $DB; $label = strtolower($label); if ($wildcard_search) { $count = 0; $label = str_replace('*', '%', $label, $count); if ($count == 0) { $label = '%'.$label.'%'; } $relation = ['LIKE', $label]; } else { $relation = $label; } $IDs = []; foreach (['NetworkName' => 'glpi_networknames', 'NetworkAlias' => 'glpi_networkaliases'] as $class => $table) { $criteria = [ 'SELECT' => 'id', 'FROM' => $table, 'WHERE' => ['name' => $relation] ]; if (is_array($fqdns_id) && count($fqdns_id) > 0 || is_int($fqdns_id) && $fqdns_id > 0 ) { $criteria['WHERE']['fqdns_id'] = $fqdns_id; } $iterator = $DB->request($criteria); while ($element = $iterator->next()) { $IDs[$class][] = $element['id']; } } return $IDs; } /** * Look for "computer name" inside all databases * * @param string $fqdn name to search (for instance : forge.indepnet.net) * @param boolean $wildcard_search true if we search with wildcard (false by default) * * @return array * each value of the array (corresponding to one NetworkPort) is an array of the * items from the master item to the NetworkPort **/ static function getItemsByFQDN($fqdn, $wildcard_search = false) { $FQNDs_with_Items = []; if (!$wildcard_search) { if (!FQDN::checkFQDN($fqdn)) { return []; } } $position = strpos($fqdn, "."); if ($position !== false) { $label = strtolower(substr( $fqdn, 0, $position)); $fqdns_id = FQDN::getFQDNIDByFQDN(substr( $fqdn, $position + 1), $wildcard_search); } else { $label = $fqdn; $fqdns_id = -1; } foreach (self::getIDsByLabelAndFQDNID($label, $fqdns_id, $wildcard_search) as $class => $IDs) { if ($FQDNlabel = getItemForItemtype($class)) { foreach ($IDs as $ID) { if ($FQDNlabel->getFromDB($ID)) { $FQNDs_with_Items[] = array_merge(array_reverse($FQDNlabel->recursivelyGetItems()), [clone $FQDNlabel]); } } } } return $FQNDs_with_Items; } /** * Get an Object ID by its name (only if one result is found in the entity) * * @param string $value the name * @param integer $entity the entity to look for * * @return array an array containing the object ID * or an empty array is no value of serverals ID where found **/ static function getUniqueItemByFQDN($value, $entity) { $labels_with_items = self::getItemsByFQDN($value); // Filter : Do not keep ip not linked to asset if (count($labels_with_items)) { foreach ($labels_with_items as $key => $tab) { if (isset($tab[0]) && (($tab[0] instanceof NetworkName) || ($tab[0] instanceof NetworkPort) || $tab[0]->isDeleted() || $tab[0]->isTemplate() || ($tab[0]->getEntityID() != $entity))) { unset($labels_with_items[$key]); } } } if (count($labels_with_items)) { // Get the first item that is matching entity foreach ($labels_with_items as $items) { foreach ($items as $item) { if ($item->getEntityID() == $entity) { $result = ["id" => $item->getID(), "itemtype" => $item->getType()]; unset($labels_with_items); return $result; } } } } return []; } }