function ona_find_host($search = "") { global $conf, $self, $onadb; printmsg("DEBUG => ona_find_host({$search}) called", 3); // By record ID? if (is_numeric($search)) { list($status, $rows, $host) = ona_get_host_record(array('id' => $search)); if ($rows) { printmsg("DEBUG => ona_find_host({$search}) called, found: {$host['fqdn']}", 3); return array($status, $rows, $host); } } // By Interface ID or IP address? list($status, $rows, $interface) = ona_find_interface($search); if (!$status and $rows) { // Load and return associated info list($status, $rows, $host) = ona_get_host_record(array('id' => $interface['host_id'])); return array($status, $rows, $host); } // MP: NEEDS MORE VALIDATION ON THIS PART!! // If it does not have a dot in it. append the default domain if (!strstr($search, '.')) { $search = $search . '.' . $conf['dns_defaultdomain']; } // // It's an FQDN, do a bunch of stuff! // // lets test out if it has a / in it to strip the view name portion $view['id'] = 0; if (strstr($search, '/')) { list($dnsview, $search) = explode('/', $search); list($status, $rows, $view) = db_get_record($onadb, 'dns_views', array('name' => strtoupper($dnsview))); printmsg("DEBUG => ona_find_host: DNS view [{$dnsview}] was not found, using default", 2); if (!$rows) { $view['id'] = 0; } } // FIXME: MP this will currently "fail" if the fqdn of the server // is the same as a valid domain name. not sure why anyone would have this but // never say never. I'll leave this issue unfixed for now // Find the 'first', domain name piece of $search list($status, $rows, $domain) = ona_find_domain($search, 0); if (!isset($domain['id'])) { printmsg("ERROR => Unable to determine domain name portion of ({$search})!", 3); $self['error'] = "ERROR => Unable to determine domain name portion of ({$search})!"; return array(3, $self['error'] . "\n"); } printmsg("DEBUG => ona_find_domain({$search}) returned: {$domain['fqdn']}", 3); // Now find what the host part of $search is $hostname = str_replace(".{$domain['fqdn']}", '', $search); // Let's see if that hostname is valid or not in $domain['id'] $domain_parts = explode('.', $domain['fqdn']); foreach ($domain_parts as $part) { // Loop through the parts of the domain to find host.sub domain.com type entries.. list($status, $dnsrows, $dnsrecs) = db_get_records($onadb, 'dns', array('domain_id' => $domain['id'], 'name' => $hostname, 'dns_view_id' => $view['id'])); // If we didnt just find a dns record.. lets move the period over and try a deeper domain/host pair. if (!$dnsrows) { $hostname = $hostname . '.' . $part; $name = str_replace("{$part}.", '', $domain['fqdn']); list($status, $rows, $domain) = ona_get_domain_record(array('name' => $name)); } else { break; } } // If we found one or more dns records, lets loop through them all and find the first primary host using that name if ($dnsrows) { foreach ($dnsrecs as $entry) { list($status, $rows, $host) = ona_get_host_record(array('primary_dns_id' => $entry['id'])); if ($host['id']) { return array($status, $rows, $host); } } } // Otherwise, build a fake host record with only a few entries in it and return that $host = array('id' => 0, 'name' => $hostname, 'fqdn' => "{$hostname}.{$domain['fqdn']}", 'domain_id' => $domain['id'], 'domain_fqdn' => $domain['fqdn']); return array(0, 0, $host); }
function dns_record_modify($options = "") { global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.13'; printmsg("DEBUG => dns_record_modify({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !$options['set_name'] and !$options['set_ip'] and !$options['set_ttl'] and !$options['set_pointsto'] and !$options['set_srv_pri'] and !$options['set_srv_weight'] and !$options['set_srv_port'] and !$options['set_mx_preference'] and !$options['set_notes'] and !$options['set_view']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dns_record_modify-v{$version} Modify a DNS record Synopsis: dns_record_modify [KEY=VALUE] ... Where: name=NAME[.DOMAIN] or ID select dns record by name or ID Update: set_name=NAME[.DOMAIN] change name and/or domain set_ip=ADDRESS change IP the record points to set_ttl=NUMBER change the TTL value, 0 = use domains TTL value set_pointsto=NAME[.DOMAIN] change where a CNAME points set_notes=NOTES change the textual notes set_mx_preference=NUMBER change the MX record preference value set_txt=STRING change the value of the TXT record set_srv_pri=NUMBER change SRV Priority set_srv_weight=NUMBER change SRV Weight set_srv_port=NUMBER change SRV Port set_ebegin change the begin date for record, 0 disables set_domain=DOMAIN use if you need to explicitly set domain set_view=STRING change DNS view identifier. AKA Split horizon. Note: * You are not allowed to change the type of the DNS record, to do that you must delete and re-add the record with the new type. * DOMAIN will default to {$conf['dns_defaultdomain']} if not specified EOM ); } /* Modify logic 1. find the dns record we are editing 2. If it is an A, check that the name we are changing to does not already match an existing A/ip or CNAME 3. if its a CNAME, check that it is not the same as any other records. */ // Check permissions if (!auth('host_modify')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // Sanitize addptr.. set it to Y if it is not set $options['set_addptr'] = sanitize_YN($options['set_addptr'], 'Y'); // clean up what is passed in $options['set_ip'] = trim($options['set_ip']); $options['set_pointsto'] = trim($options['set_pointsto']); $options['set_name'] = trim($options['set_name']); $options['set_domain'] = trim($options['set_domain']); $options['set_txt'] = trim($options['set_txt']); //$options['set_view'] = trim($options['set_view']); // // Find the dns record we're modifying // // If the name we were passed has a leading . in it then remove the dot. $options['set_name'] = preg_replace("/^\\./", '', $options['set_name']); // Find the DNS record from $options['name'] list($status, $rows, $dns) = ona_find_dns_record($options['name']); printmsg("DEBUG => dns_record_modify() DNS record: {$dns['fqdn']}", 3); if ($rows > 1) { printmsg("DEBUG => Found more than one DNS record for: {$options['name']}", 3); $self['error'] = "ERROR => Found more than one DNS record for: {$options['name']}"; return array(2, $self['error'] . "\n"); } // If we didn't get a record then exit if (!$dns['id']) { printmsg("DEBUG => DNS record not found ({$options['name']})!", 3); $self['error'] = "ERROR => DNS record not found ({$options['name']})!"; return array(4, $self['error'] . "\n"); } // Set the current_name variable with the records current name // Used by the add pointer function below since it runs before any names are updated $current_name = $dns['fqdn']; $current_int_id = $dns['interface_id']; $check_dns_view_id = $dns['dns_view_id']; $current_dns_view_id = $dns['dns_view_id']; // Set status on if we are chaning IP addresses $changingint = 0; $changingview = 0; // Set a message to display when using dns views if ($conf['dns_views']) { $viewmsg = ' Ensure you are selecting the proper DNS view for this record.'; } // // Define the records we're updating // // This variable will contain the updated info we'll insert into the DB $SET = array(); // Gather DNS view information if (array_key_exists('set_view', $options)) { if (is_numeric($options['set_view'])) { $viewsearch = array('id' => $options['set_view']); } else { $viewsearch = array('name' => strtoupper($options['set_view'])); } // find the IP interface record, list($status, $rows, $dnsview) = ona_get_dns_view_record($viewsearch); if (!$rows) { printmsg("ERROR => dns_record_modify() Unable to find DNS view: {$options['set_view']}", 3); $self['error'] = "ERROR => dns_record_modify() Unable to find DNS view: {$options['set_view']}."; return array(4, $self['error'] . "\n"); } // If we have a new dns view, add it to the SET array and update the check view variable used in all the checks. if ($dns['dns_view_id'] != $dnsview['id']) { // You can only change the view on parent records.. if this record has a dns_id, you must change the parent if ($dns['dns_id']) { printmsg("ERROR => You must change the parent DNS A record to the new view. This record will follow.", 3); $self['error'] = "ERROR => You must change the parent DNS A record to the new view. This record will follow."; return array(5, $self['error'] . "\n"); } $SET['dns_view_id'] = $dnsview['id']; $check_dns_view_id = $dnsview['id']; $changingview = 1; } } // Checking the IP setting first to estabilish if we are changing the IP so I can check the new combo of A/ip later if ($options['set_ip'] and $options['set_ip'] != '0.0.0.0') { // find the IP interface record, to ensure it is valid list($status, $rows, $interface) = ona_find_interface($options['set_ip']); if (!$rows) { printmsg("ERROR => dns_record_modify() Unable to find IP interface: {$options['set_ip']}", 3); $self['error'] = "ERROR => dns_record_modify() Unable to find IP interface: {$options['set_ip']}\n"; return array(4, $self['error']); } // If they actually changed the ip address if ($interface['id'] != $dns['interface_id']) { // check for child records that would match our new values // I think they will always be just PTR records so I am only selecting that type for now? list($status, $rows, $dnschild) = ona_get_dns_record(array('dns_id' => $dns['id'], 'interface_id' => $interface['id'], 'type' => 'PTR')); if ($rows) { printmsg("ERROR => dns_record_modify() This change results in a duplicate child DNS record: PTR {$options['set_ip']}. Delete existing PTR record first.", 3); $self['error'] = "<br>ERROR => dns_record_modify() This change results in a duplicate child DNS record: PTR {$options['set_ip']}.<br> Delete existing PTR record first.\n"; return array(4, $self['error']); } $changingint = 1; $SET['interface_id'] = $interface['id']; // get the info on the original interface list($status, $rows, $origint) = ona_get_interface_record(array('id' => $dns['interface_id'])); } } // Set options['set_name']? // Validate that the DNS name has only valid characters in it if ($options['set_name']) { // If we are specifically passing in a domain, use its value. If we dont have a domain // then try to find it in the name that we are setting. if ($options['set_domain']) { // Find the domain name piece of $search list($status, $rows, $domain) = ona_find_domain($options['set_domain'], 0); } else { list($status, $rows, $domain) = ona_find_domain($options['set_name'], 0); } // Find the domain name piece of $search if (!isset($domain['id'])) { printmsg("ERROR => Unable to determine domain name portion of ({$options['set_name']})!", 3); $self['error'] = "ERROR => Unable to determine domain name portion of ({$options['set_name']})!"; return array(3, $self['error'] . "\n"); } printmsg("DEBUG => ona_find_domain({$options['set_name']}) returned: {$domain['fqdn']} for new name.", 3); // Now find what the host part of $search is $hostname = str_replace(".{$domain['fqdn']}", '', $options['set_name']); // Validate that the DNS name has only valid characters in it $hostname = sanitize_hostname($hostname); if (!$hostname) { printmsg("DEBUG => Invalid host name ({$options['set_name']})!", 3); $self['error'] = "ERROR => Invalid host name ({$options['set_name']})!"; return array(4, $self['error'] . "\n"); } // If the hostname we came up with and the domain name are the same, then assume this is // meant to be a domain specific record, like A, MX, NS type records. if ($hostname == $domain['fqdn']) { $hostname = ''; } // Debugging printmsg("DEBUG => Using hostname: {$hostname}.{$domain['fqdn']}, Domain ID: {$domain['id']}", 3); // if it is an a record and we are changing the name.. make sure there is not already an A with that name/ip combo if ($dns['type'] == 'A') { // If we are changing the interface id as determined above, check using that value if ($changingint) { $dns['interface_id'] = $SET['interface_id']; } list($status, $rows, $tmp) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'interface_id' => $dns['interface_id'], 'type' => 'A', 'dns_view_id' => $check_dns_view_id)); if ($rows) { if ($tmp['id'] != $dns['id'] or $rows > 1) { printmsg("ERROR => There is already an A record with that name and IP address!{$viewmsg}", 3); $self['error'] = "ERROR => There is already an A record with that name and IP address!{$viewmsg}"; return array(5, $self['error'] . "\n"); } } } // make sure that name/pointsto combo doesnt already exist if ($dns['type'] == 'CNAME' or $dns['type'] == 'MX' or $dns['type'] == 'NS' or $dns['type'] == 'SRV') { list($status, $rows, $tmp) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'dns_id' => $dns['dns_id'], 'type' => $dns['type'], 'dns_view_id' => $check_dns_view_id)); if ($rows) { if ($tmp['id'] != $dns['id'] or $rows > 1) { printmsg("ERROR => There is already a {$dns['type']} with that name pointing to that A record!{$viewmsg}", 3); $self['error'] = "ERROR => There is already a {$dns['type']} with that name pointing to that A record!{$viewmsg}"; return array(6, $self['error'] . "\n"); } } } if ($dns['type'] == 'CNAME') { // if it is a CNAME, make sure the new name is not an A record name already list($status, $rows, $tmp) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'type' => 'A', 'dns_view_id' => $check_dns_view_id)); if ($status or $rows) { printmsg("ERROR => There is already an A record with that name!{$viewmsg}", 3); $self['error'] = "ERROR => There is already an A record with that name!{$viewmsg}"; return array(7, $self['error'] . "\n"); } } // lets try and determine the interface record using the name passed in. Only works if we get one record back // this is all to help associate if it can so that when the A record is removed, so is this TXT record. if ($dns['type'] == 'TXT') { // if we are dealing with a change to a domain only.. then blank the interface id and dns_id if ($hostname == '') { $SET['interface_id'] = ''; $SET['dns_id'] = ''; } else { list($status, $rows, $hostint) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'type' => 'A', 'dns_view_id' => $check_dns_view_id)); if ($rows == 1) { $SET['interface_id'] = $hostint['interface_id']; $SET['dns_id'] = $hostint['id']; $SET['name'] = $hostname; } } } // If you have actually changed the name from what it was, set the new variable $SET if ($dns['name'] != $hostname) { $SET['name'] = $hostname; } if ($dns['domain_id'] != $domain['id']) { $SET['domain_id'] = $domain['id']; } } // If we are modifying a pointsto option if (array_key_exists('set_pointsto', $options) and ($options['set_type'] == 'CNAME' or $options['set_type'] == 'MX' or $options['set_type'] == 'NS' or $options['set_type'] == 'SRV')) { // Determine the host and domain name portions of the pointsto option // Find the domain name piece of $search list($status, $rows, $pdomain) = ona_find_domain($options['set_pointsto']); printmsg("DEBUG => ona_find_domain({$options['set_pointsto']}) returned: {$domain['fqdn']} for pointsto.", 3); // Now find what the host part of $search is $phostname = str_replace(".{$pdomain['fqdn']}", '', $options['set_pointsto']); // Validate that the DNS name has only valid characters in it $phostname = sanitize_hostname($phostname); if (!$phostname) { printmsg("DEBUG => Invalid pointsto host name ({$options['set_pointsto']})!", 3); $self['error'] = "ERROR => Invalid pointsto host name ({$options['set_pointsto']})!"; return array(4, $self['error'] . "\n"); } // Debugging printmsg("DEBUG => Using 'pointsto' hostname: {$phostname}.{$pdomain['fqdn']}, Domain ID: {$pdomain['id']}", 3); // Find the dns record that it will point to list($status, $rows, $pointsto_record) = ona_get_dns_record(array('name' => $phostname, 'domain_id' => $pdomain['id'], 'type' => 'A', 'dns_view_id' => $check_dns_view_id)); if ($status or !$rows) { printmsg("ERROR => Unable to find DNS A record to point {$options['set_type']} entry to!{$viewmsg}", 3); $self['error'] = "ERROR => Unable to find DNS A record to point {$options['set_type']} entry to!{$viewmsg}"; return array(5, $self['error'] . "\n"); } // Validate that there are no entries already pointed to the new A record list($c_status, $c_rows, $c_record) = ona_get_dns_record(array('name' => $dns['name'], 'domain_id' => $dns['domain_id'], 'dns_id' => $pointsto_record['id'], 'type' => $options['set_type'], 'dns_view_id' => $check_dns_view_id)); if ($c_record['id'] != $dns['id'] and $c_rows) { printmsg("ERROR => Another DNS {$options['set_type']} record exists with the values you've selected!{$viewmsg}", 3); $self['error'] = "ERROR => Another DNS {$options['set_type']} record exists with the values you've selected!{$viewmsg}"; return array(5, $self['error'] . "\n"); } $SET['dns_id'] = $pointsto_record['id']; $SET['interface_id'] = $pointsto_record['interface_id']; } // Set options['set_notes'] (it can be a null string!) if (array_key_exists('set_notes', $options)) { // There is an issue with escaping '=' and '&'. We need to avoid adding escape characters $options['set_notes'] = str_replace('\\=', '=', $options['set_notes']); $options['set_notes'] = str_replace('\\&', '&', $options['set_notes']); // If it changed... if ($dns['notes'] != $options['set_notes']) { $SET['notes'] = $options['set_notes']; } } // Check the date formatting etc if (isset($options['set_ebegin']) and $options['set_ebegin'] != $dns['ebegin']) { // format the time that was passed in for the database, leave it as 0 if they pass it as 0 $options['set_ebegin'] = $options['set_ebegin'] == '0' ? 0 : date('Y-m-j G:i:s', strtotime($options['set_ebegin'])); // Force the SET variable if its ont 0 and the current record is not 0000:00:00 00:00 if (!($options['set_ebegin'] == '0' and $dns['ebegin'] == '0000-00-00 00:00:00')) { $SET['ebegin'] = $options['set_ebegin']; } } else { // If I got no date, use right now as the date/time $options['set_ebegin'] = date('Y-m-j G:i:s'); } // Add the remaining items to the $SET variable // if there is a ttl setting and it is not the same as the existing record if (array_key_exists('set_ttl', $options) and $options['set_ttl'] != $dns['ttl']) { $SET['ttl'] = $options['set_ttl']; } if (array_key_exists('set_mx_preference', $options) and $options['set_mx_preference'] != $dns['mx_preference']) { $SET['mx_preference'] = $options['set_mx_preference']; } if (array_key_exists('set_srv_pri', $options) and $options['set_srv_pri'] != $dns['srv_pri']) { $SET['srv_pri'] = $options['set_srv_pri']; } if (array_key_exists('set_srv_weight', $options) and $options['set_srv_weight'] != $dns['srv_weight']) { $SET['srv_weight'] = $options['set_srv_weight']; } if (array_key_exists('set_srv_port', $options) and $options['set_srv_port'] != $dns['srv_port']) { $SET['srv_port'] = $options['set_srv_port']; } if (array_key_exists('set_txt', $options)) { // There is an issue with escaping '=' and '&'. We need to avoid adding escape characters $options['set_txt'] = str_replace('\\=', '=', $options['set_txt']); $options['set_txt'] = str_replace('\\&', '&', $options['set_txt']); // If it changed... if ($dns['txt'] != $options['set_txt']) { $SET['txt'] = $options['set_txt']; } } // If it is an A record and they have specified to auto add the PTR record for it. if ($options['set_addptr'] == 'Y' and $options['set_type'] == 'A') { printmsg("DEBUG => Auto adding a PTR record for {$options['set_name']}.", 0); // Run dns_record_add as a PTR type // Always use the $current_name variable as the name might change during the update list($status, $output) = run_module('dns_record_add', array('name' => $current_name, 'domain' => $domain['fqdn'], 'ip' => $options['set_ip'], 'ebegin' => $options['set_ebegin'], 'type' => 'PTR', 'view' => $check_dns_view_id)); if ($status) { return array($status, $output); } printmsg($text); } // Get the dns record before updating (logging) $original_record = $dns; // Update the host record if necessary //if(count($SET) > 0 and $options['set_ebegin'] != $dns['ebegin']) { if (count($SET) > 0) { // Use the ebegin value set above $SET['ebegin'] = $options['set_ebegin']; // If we are changing the interface id as determined above, check using that value if ($changingint) { // If the interface id has changed, make sure any child records are updated first if ($SET['interface_id'] != $current_int_id) { printmsg("DEBUG = > dns_record_modify() Updating child interfaces to new interface.", 2); list($status, $rows) = db_update_record($onadb, 'dns', array('dns_id' => $dns['id'], 'interface_id' => $current_int_id), array('interface_id' => $SET['interface_id'])); if ($status) { $self['error'] = "ERROR => dns_record_modify() SQL Query failed for dns record: " . $self['error']; printmsg($self['error'], 0); return array(11, $self['error'] . "\n"); } // TODO: may need set rebuild flag on each of the domains related to these child records that just changed } // Check the PTR record has the proper domain still $ipflip = ip_mangle($interface['ip_addr_text'], 'flip'); $octets = explode(".", $ipflip); if (count($octets) > 4) { $arpa = '.ip6.arpa'; $octcount = 31; } else { $arpa = '.in-addr.arpa'; $octcount = 3; } // Find a pointer zone for this record to associate with. list($status, $prows, $ptrdomain) = ona_find_domain($ipflip . $arpa); list($status, $drrows, $dnsrec) = ona_get_dns_record(array('type' => 'PTR', 'interface_id' => $SET['interface_id'], 'dns_view_id' => $check_dns_view_id)); // TRIGGER: we made a change and need to update the CURRENT PTR record as well, only sets it if the ptrdomain changes list($status, $rows) = db_update_record($onadb, 'dns_server_domains', array('domain_id' => $dnsrec['domain_id']), array('rebuild_flag' => 1)); if ($status) { $self['error'] = "ERROR => dns_record_add() Unable to update rebuild flags for domain.: {$self['error']}"; printmsg($self['error'], 0); return array(7, $self['error'] . "\n"); } // if we find any PTR records and the domain has chaned, make sure the child PTR records have the updated PTR domain info. if (isset($ptrdomain['id']) and $drrows > 0 and $dnsrec['domain_id'] != $ptrdomain['id']) { list($status, $rows) = db_update_record($onadb, 'dns', array('id' => $dnsrec['id']), array('domain_id' => $ptrdomain['id'], 'ebegin' => $SET['ebegin'])); if ($status or !$rows) { $self['error'] = "ERROR => dns_record_modify() Child PTR record domain update failed: " . $self['error']; printmsg($self['error'], 0); return array(14, $self['error'] . "\n"); } // TRIGGER: we made a change and need to update the NEW PTR record as well, only sets it if the ptrdomain changes list($status, $rows) = db_update_record($onadb, 'dns_server_domains', array('domain_id' => $ptrdomain['id']), array('rebuild_flag' => 1)); if ($status) { $self['error'] = "ERROR => dns_record_add() Unable to update rebuild flags for domain.: {$self['error']}"; printmsg($self['error'], 0); return array(7, $self['error'] . "\n"); } } } // If we are changing the view, we must change all other DNS records that point to this one to the same view. if ($changingview) { if ($SET['dns_view_id'] != $current_dns_view_id) { printmsg("DEBUG = > dns_record_modify() Updating child DNS records to new dns view.", 2); list($status, $rows) = db_update_record($onadb, 'dns', array('dns_id' => $dns['id']), array('dns_view_id' => $SET['dns_view_id'])); if ($status) { $self['error'] = "ERROR => dns_record_modify() SQL Query failed for dns record child view updates: " . $self['error']; printmsg($self['error'], 0); return array(11, $self['error'] . "\n"); } } // TRIGGER: yep I probably need one here FIXME } // Make sure we us A type for both A and AAAA if ($SET['type'] == 'AAAA') { $SET['type'] = 'A'; } // Change the actual DNS record list($status, $rows) = db_update_record($onadb, 'dns', array('id' => $dns['id']), $SET); if ($status or !$rows) { $self['error'] = "ERROR => dns_record_modify() SQL Query failed for dns record: " . $self['error']; printmsg($self['error'], 0); return array(12, $self['error'] . "\n"); } // TRIGGER: we made a change, lets mark the domain for rebuild on its servers list($status, $rows) = db_update_record($onadb, 'dns_server_domains', array('domain_id' => $dns['domain_id']), array('rebuild_flag' => 1)); if ($status) { $self['error'] = "ERROR => dns_record_add() Unable to update rebuild flags for domain.: {$self['error']}"; printmsg($self['error'], 0); return array(7, $self['error'] . "\n"); } // TRIGGER: If we are changing domains, lets flag the new domain as well, lets mark the domain for rebuild on its servers if ($SET['domain_id']) { list($status, $rows) = db_update_record($onadb, 'dns_server_domains', array('domain_id' => $SET['domain_id']), array('rebuild_flag' => 1)); if ($status) { $self['error'] = "ERROR => dns_record_add() Unable to update rebuild flags for domain.: {$self['error']}"; printmsg($self['error'], 0); return array(7, $self['error'] . "\n"); } } } // Get the host record after updating (logging) list($status, $rows, $new_record) = ona_get_dns_record(array('id' => $dns['id'])); // Return the success notice $self['error'] = "INFO => DNS record UPDATED:{$dns['id']}: {$new_record['fqdn']}"; $log_msg = "INFO => DNS record UPDATED:{$dns['id']}: "; $more = ''; foreach (array_keys($original_record) as $key) { if ($original_record[$key] != $new_record[$key]) { $log_msg .= $more . $key . "[" . $original_record[$key] . "=>" . $new_record[$key] . "]"; $more = "; "; } } // only print to logfile if a change has been made to the record if ($more != '') { printmsg($log_msg, 0); } return array(0, $self['error'] . "\n"); }
function quick_search($q) { global $conf, $self; // // *** Quick Search *** // // If it's an IP or MAC address (string or numeric): // Look for an interface and display associated host record // Look for the subnet that IP is on and display a single subnet record // If it's a string: // Look for a hostname // Look for an alias name (and display associated hosts) // Look for a subnet name printmsg("DEBUG => quick_search({$q}) called", 3); // Check to see if it is a MAC.. do it here instead of in the next interface section // so that we can properly find multiple hosts with the same mac $mac = mac_mangle($q, 1); if ($mac != -1) { printmsg("DEBUG => quick_search() Looks like a MAC, Returning mac = {$q}", 3); return array('hosts', array('mac' => $q)); } // See if $q identifies an interface record (by IP, MAC, etc) list($status, $rows, $record) = ona_find_interface($q); // If it was, display the associated host record if ($rows) { printmsg("DEBUG => quick_search() returning host match (ID={$record['host_id']})", 3); return array('hosts', array('host_id' => $record['host_id'])); } // See if $q identifies a subnet record (by IP, ID, or Description) list($status, $rows, $record) = ona_find_subnet($q); // If it was, display the associated subnet record if ($rows) { printmsg("DEBUG => quick_search() returning subnet match (ID={$record['id']})", 3); return array('subnets', array('subnet_id' => $record['id'])); } // Well, I guess we'll assume $q is a hostname/alias search printmsg("DEBUG => quick_search() found no subnet or host match. Returning hostname = {$q}", 3); return array('hosts', array('hostname' => $q)); }
function domain_server_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.02'; printmsg("DEBUG => domain_server_add({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !($options['domain'] and $options['server'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM domain_server_add-v{$version} Assigns an existing domain record to a DNS server Synopsis: domain_server_add [KEY=VALUE] ... Required: domain=NAME or ID domain name or ID server=NAME[.DOMAIN] or ID server name or ID role=master|slave|forward role of this server for this domain EOM ); } // if (is_numeric($options['domain'])) { // $domainsearch['id'] = $options['domain']; // } else { // $domainsearch['name'] = strtolower($options['domain']); // } // Determine the entry itself exists list($status, $rows, $domain) = ona_find_domain($options['domain'], 0); // Test to see that we were able to find the specified record if (!$domain['id']) { printmsg("DEBUG => Unable to find the domain record using {$options['domain']}!", 3); $self['error'] = "ERROR => Unable to find the domain record using {$options['domain']}!"; return array(4, $self['error'] . "\n"); } printmsg("DEBUG => domain_server_add(): Found domain, {$domain['name']}", 3); // Determine the server is valid list($status, $rows, $ns_dns) = ona_find_dns_record($options['server']); list($status, $rows, $interface) = ona_find_interface($ns_dns['interface_id']); $host['id'] = $interface['host_id']; if (!$host['id']) { printmsg("DEBUG => The server ({$options['server']}) does not exist!", 3); $self['error'] = "ERROR => The server specified, {$options['server']}, does not exist!"; return array(2, $self['error'] . "\n"); } // what is the role for this server. switch (strtolower($options['role'])) { case "forward": $role = "forward"; break; case "master": $role = "master"; break; case "slave": $role = "slave"; break; default: $role = "master"; } // Check permissions if (!auth('advanced')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(12, $self['error'] . "\n"); } // Test that this domain isnt already assigned to the server list($status, $rows, $domainserver) = ona_get_dns_server_domain_record(array('host_id' => $host['id'], 'domain_id' => $domain['id'])); if ($rows) { printmsg("DEBUG => Domain {$domain['name']} already assigned to {$options['server']}", 3); $self['error'] = "ERROR => Domain {$domain['name']} already assigned to {$options['server']}"; return array(11, $self['error'] . "\n"); } // Get the next ID $id = ona_get_next_id('dns_server_domains'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); return array(6, $add_to_error . $self['error'] . "\n"); } printmsg("DEBUG => domain_server_add(): New DNS server domain ID: {$id}", 3); // Add new record to dns_server_domains list($status, $rows) = db_insert_record($onadb, 'dns_server_domains', array('id' => $id, 'host_id' => $host['id'], 'domain_id' => $domain['id'], 'role' => $role, 'rebuild_flag' => 1)); if ($status or !$rows) { $self['error'] = "ERROR => domain_server_add() SQL Query failed:" . $self['error']; printmsg($self['error'], 0); return array(8, $add_to_error . $self['error'] . "\n"); } // Test that there are no NS records for this pair already // ASSUMPTION: MP this will always be just one record?? list($status, $dnsrows, $dnsrec) = db_get_record($onadb, 'dns', "domain_id = {$domain['id']} AND type = 'NS' AND interface_id in (select id from interfaces where host_id = {$host['id']})"); // Auto add the NS record if there were none found already. the user can remove any NS records they dont want afterwards if (!$dnsrows) { printmsg("DEBUG => Auto adding a NS record for {$options['server']}.", 0); // Run dns_record_add as a NS type list($status, $output) = run_module('dns_record_add', array('name' => $domain['fqdn'], 'pointsto' => $options['server'], 'type' => 'NS')); if ($status) { return array($status, $output); } $add_to_error .= $output; } else { printmsg("DEBUG => Found existing NS record for {$options['server']}. Skipping the auto add.", 0); } // Return the success notice $self['error'] = "INFO => DNS Domain/Server Pair ADDED: {$domain['name']}/{$options['server']} "; printmsg($self['error'], 0); return array(0, $add_to_error . $self['error'] . "\n"); }
function rpt_get_data($form) { global $base, $onadb; // If they want to perform a scan on an existing file if ($form['subnet']) { $rptdata['scansource'] = "Based on an existing scan file for '{$form['subnet']}'"; //$xml = shell_exec("{$nmapcommand} -sP -R -oX - {$form['subnet']}"); list($status, $rows, $subnet) = ona_find_subnet($form['subnet']); if ($rows) { $netip = ip_mangle($subnet['ip_addr'], 'dotted'); $netcidr = ip_mangle($subnet['ip_mask'], 'cidr'); $nmapxmlfile = "{$base}/local/nmap_scans/subnets/{$netip}-{$netcidr}.xml"; if (file_exists($nmapxmlfile)) { $xml[0] = xml2ary(file_get_contents($nmapxmlfile)); } else { $self['error'] = "ERROR => The subnet '{$form['subnet']}' does not have an nmap scan XML file on this server. {$nmapxmlfile}"; return array(2, $self['error'] . "\n"); } } else { $self['error'] = "ERROR => The subnet '{$form['subnet']}' does not exist."; return array(2, $self['error'] . "\n"); } } // If they want to build a report on ALL the nmap data if ($form['all']) { $rptdata['scansource'] = "Showing all scan data"; $nmapdir = "{$base}/local/nmap_scans/subnets"; $dh = @opendir($nmapdir); $c = 0; while (false !== ($filename = @readdir($dh))) { if (strpos($filename, 'xml')) { $xml[$c] = xml2ary(file_get_contents($nmapdir . '/' . $filename)); } $c++; } } // If they pass a file from the remote host via CLI if ($form['file']) { $rptdata['scansource'] = "Based on an uploaded XML file"; $nmapxmlfile = $form['file']; // clean up escaped characters $nmapxmlfile = preg_replace('/\\\\"/', '"', $nmapxmlfile); $nmapxmlfile = preg_replace('/\\\\=/', '=', $nmapxmlfile); $nmapxmlfile = preg_replace('/\\\\&/', '&', $nmapxmlfile); $xml[0] = xml2ary($nmapxmlfile); } // loop through all the xml arrays that have been built. for ($z = 0; $z < count($xml); $z++) { // Find out how many total hosts we have in the array $rptdata['totalhosts'] = $xml[$z]['nmaprun']['_c']['runstats']['_c']['hosts']['_a']['total']; $rptdata['runtime'] = $xml[$z]['nmaprun']['_c']['runstats']['_c']['finished']['_a']['timestr']; // pull args to find subnet/cidr $rptdata['args'] = $xml[$z]['nmaprun']['_a']['args']; // process args list($subnetaddr, $netcidr) = explode('/', preg_replace("/.* (.*)\\/(\\d+)\$/", "\\1/\\2", $rptdata['args'])); $netip = ip_mangle($subnetaddr, 'dotted'); $netcidr = ip_mangle($netcidr, 'cidr'); // Process the array for the total amount of hosts reported for ($i = 0; $i < $rptdata['totalhosts']; $i++) { // Clear MAC each itteration of the loop $macaddr = ''; // Gather some info from the nmap XML file $netstatus = $xml[$z]['nmaprun']['_c']['host'][$i]['_c']['status']['_a']['state']; $ipaddr = $xml[$z]['nmaprun']['_c']['host'][$i]['_c']['address']['_a']['addr']; //$macaddr = $xml['nmaprun']['_c']['host'][$i]['_c']['address']['_a']['addr']; $dnsname = $xml[$z]['nmaprun']['_c']['host'][$i]['_c']['hostnames']['_c']['hostname']['_a']['name']; $dnsrows = 0; $dns = array(); // Try the older nmap format if no IP found.. not sure of what differences there are in the XSL used? if (!$ipaddr) { $ipaddr = $xml[$z]['nmaprun']['_c']['host'][$i]['_c']['address']['0']['_a']['addr']; $macaddr = $xml[$z]['nmaprun']['_c']['host'][$i]['_c']['address']['1']['_a']['addr']; } // Lookup the IP address in the database if ($ipaddr) { list($status, $introws, $interface) = ona_find_interface($ipaddr); if (!$introws) { $interface['ip_addr_text'] = 'NOT FOUND'; list($status, $introws, $tmp) = ona_find_subnet($ipaddr); $interface['subnet_id'] = $tmp['id']; } else { // Lookup the DNS name in the database list($status, $dnsrows, $dnscount) = db_get_records($onadb, 'dns', "interface_id = {$interface['id']}", "", 0); list($status, $dnsptrrows, $dnsptr) = ona_get_dns_record(array('interface_id' => $interface['id'], 'type' => 'PTR')); list($status, $dnsprows, $dns) = ona_get_dns_record(array('id' => $dnsptr['dns_id'])); } } // Find out if this IP falls inside of a pool $inpool = 0; $ip = ip_mangle($ipaddr, 'numeric'); if ($ip > 0) { list($status, $poolrows, $pool) = ona_get_dhcp_pool_record("ip_addr_start <= '{$ip}' AND ip_addr_end >= '{$ip}'"); } if ($poolrows) { $inpool = 1; } // some base logic // if host is up in nmap but no db ip then put in $nodb // if host is up and is in db then put in $noissue // if host is down and not in db then skip // if host is down and in db then put in $nonet // if host is up an in db, does DNS match? // in DNS but not DB // in DB but not DNS // DNS and DB dont match // Setup the base array element for the IP $rptdata['ip'][$ipaddr] = array(); $rptdata['ip'][$ipaddr]['netstatus'] = $netstatus; $rptdata['ip'][$ipaddr]['netip'] = $ipaddr; $rptdata['ip'][$ipaddr]['netdnsname'] = strtolower($dnsname); if ($macaddr != -1) { $rptdata['ip'][$ipaddr]['netmacaddr'] = $macaddr; } $rptdata['ip'][$ipaddr]['inpool'] = $inpool; $rptdata['ip'][$ipaddr]['dbip'] = $interface['ip_addr_text']; $rptdata['ip'][$ipaddr]['dbsubnetid'] = $interface['subnet_id']; $rptdata['ip'][$ipaddr]['dbdnsrows'] = $dnsrows; if (!$dns['fqdn']) { // lets see if its a PTR record if ($dnsptrrows) { // If we have a PTR for this interface, use it (never if built from ona?) $rptdata['ip'][$ipaddr]['dbdnsname'] = $dns['fqdn']; $rptdata['ip'][$ipaddr]['dbdnsptrname'] = $dnsp['fqdn']; } else { // find the hosts primary DNS record list($status, $hostrows, $host) = ona_get_host_record(array('id' => $interface['host_id'])); if ($host['fqdn']) { $host['fqdn'] = "({$host['fqdn']})"; } if ($dnsrows) { list($status, $dnstmprows, $dnstmp) = ona_get_dns_record(array('interface_id' => $interface['id'])); $rptdata['ip'][$ipaddr]['dbdnsname'] = $dnstmp['fqdn']; } else { $rptdata['ip'][$ipaddr]['dbdnsname'] = 'NO PTR'; } $rptdata['ip'][$ipaddr]['dbdnsptrname'] = $host['fqdn']; } } else { if ($dnsptrrows > 1) { $rptdata['ip'][$ipaddr]['dbdnsname'] = $dns['fqdn']; $rptdata['ip'][$ipaddr]['dbdnsptrname'] = $dnsp['fqdn']; } else { $rptdata['ip'][$ipaddr]['dbdnsname'] = $dns['fqdn']; $rptdata['ip'][$ipaddr]['dbdnsptrname'] = $dnsp['fqdn']; } } $rptdata['ip'][$ipaddr]['dbmacaddr'] = $interface['mac_addr']; $rptdata['netip'] = $netip; $rptdata['netcidr'] = $netcidr; if ($form['all']) { $rptdata['all'] = 1; } if ($form['update_response']) { $rptdata['update_response'] = 1; } } } return array(0, $rptdata); }
function host_modify($options = "") { global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.07'; printmsg("DEBUG => host_modify({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !$options['interface'] and !$options['host'] or !$options['set_host'] and !$options['set_type'] and !$options['set_location'] and !$options['set_notes']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM host_modify-v{$version} Modify a host record Synopsis: host_modify [KEY=VALUE] ... Where: host=NAME[.DOMAIN] or ID Select host by hostname or ID or interface=[ID|IP|MAC] Select host by IP or MAC Update: set_type=TYPE or ID Change device/model type or ID set_notes=NOTES Change the textual notes set_location=REF Reference for location set_device=NAME|ID Name or ID of the device this host is associated with EOM ); } // clean up what is passed in $options['interface'] = trim($options['interface']); $options['host'] = trim($options['host']); // // Find the host record we're modifying // // If they provided a hostname / ID let's look it up if ($options['host']) { list($status, $rows, $host) = ona_find_host($options['host']); } else { if ($options['interface']) { // Find an interface record by something in that interface's record list($status, $rows, $interface) = ona_find_interface($options['interface']); if ($status or !$rows) { printmsg("DEBUG => Interface not found ({$options['interface']})!", 3); $self['error'] = "ERROR => Interface not found ({$options['interface']})!"; return array(4, $self['error'] . "\n"); } // Load the associated host record list($status, $rows, $host) = ona_get_host_record(array('id' => $interface['host_id'])); } } // If we didn't get a record then exit if (!$host['id']) { printmsg("DEBUG => Host not found ({$options['host']})!", 3); $self['error'] = "ERROR => Host not found ({$options['host']})!"; return array(4, $self['error'] . "\n"); } // Get related Device record info list($status, $rows, $device) = ona_get_device_record(array('id' => $host['device_id'])); // // Define the records we're updating // // This variable will contain the updated info we'll insert into the DB $SET = array(); // Set options['set_type']? if ($options['set_type']) { // Find the Device Type ID (i.e. Type) to use list($status, $rows, $device_type) = ona_find_device_type($options['set_type']); if ($status or $rows != 1 or !$device_type['id']) { printmsg("DEBUG => The device type specified, {$options['set_type']}, does not exist!", 3); $self['error'] = "ERROR => The device type specified, {$options['set_type']}, does not exist!"; return array(6, $self['error'] . "\n"); } printmsg("DEBUG => Device type ID: {$device_type['id']}", 3); // Everything looks ok, add it to $SET if it changed... if ($device['device_type_id'] != $device_type['id']) { $SET_DEV['device_type_id'] = $device_type['id']; } } // Set options['set_notes'] (it can be a null string!) if (array_key_exists('set_notes', $options)) { // There is an issue with escaping '=' and '&'. We need to avoid adding escape characters $options['set_notes'] = str_replace('\\=', '=', $options['set_notes']); $options['set_notes'] = str_replace('\\&', '&', $options['set_notes']); // If it changed... if ($host['notes'] != $options['set_notes']) { $SET['notes'] = $options['set_notes']; } } if (array_key_exists('set_device', $options)) { list($status, $rows, $devid) = ona_find_device($options['set_device']); if (!$rows) { printmsg("DEBUG => The device specified, {$options['set_device']}, does not exist!", 3); $self['error'] = "ERROR => The device specified, {$options['set_device']}, does not exist!"; return array(7, $self['error'] . "\n"); } // set the device id if ($host['device_id'] != $devid['id']) { $SET['device_id'] = $devid['id']; } } if (array_key_exists('set_location', $options)) { if (!$options['set_location']) { unset($SET_DEV['location_id']); } else { list($status, $rows, $loc) = ona_find_location($options['set_location']); if (!$rows) { printmsg("DEBUG => The location specified, {$options['set_location']}, does not exist!", 3); $self['error'] = "ERROR => The location specified, {$options['set_location']}, does not exist!"; return array(7, $self['error'] . "\n"); } // If location is changing, then set the variable if ($device['location_id'] != $loc['id']) { $SET_DEV['location_id'] = $loc['id']; } } } // Check permissions if (!auth('host_modify')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // Get the host record before updating (logging) $original_host = $host; // Update the host record if necessary if (count($SET) > 0) { list($status, $rows) = db_update_record($onadb, 'hosts', array('id' => $host['id']), $SET); if ($status or !$rows) { $self['error'] = "ERROR => host_modify() SQL Query failed for host: " . $self['error']; printmsg($self['error'], 0); return array(8, $self['error'] . "\n"); } } // Update device table if necessary if (count($SET_DEV) > 0) { list($status, $rows) = db_update_record($onadb, 'devices', array('id' => $host['device_id']), $SET_DEV); if ($status or !$rows) { $self['error'] = "ERROR => host_modify() SQL Query failed for device type: " . $self['error']; printmsg($self['error'], 0); return array(9, $self['error'] . "\n"); } } // Get the host record after updating (logging) list($status, $rows, $new_host) = ona_get_host_record(array('id' => $host['id'])); // Return the success notice $self['error'] = "INFO => Host UPDATED:{$host['id']}: {$new_host['fqdn']}"; $log_msg = "INFO => Host UPDATED:{$host['id']}: "; $more = ""; foreach (array_keys($host) as $key) { if ($host[$key] != $new_host[$key]) { $log_msg .= "{$more}{$key}: {$host[$key]} => {$new_host[$key]}"; $more = "; "; } } // only print to logfile if a change has been made to the record if ($more != '') { printmsg($self['error'], 0); printmsg($log_msg, 0); } return array(0, $self['error'] . "\n"); }
function nat_del($options = "") { global $conf, $self, $onadb; printmsg("DEBUG => nat_del({$options}) called", 3); // Version - UPDATE on every edit! $version = '1.00'; // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !($options['natip'] and $options['ip'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM nat_del-v{$version} Delete a NAT entry from an existing IP This will delete the NAT IP interface from the subnet as well. Synopsis: nat_del [KEY=VALUE] ... Required: ip=[address|ID] the IP address or ID of the existing inside interface natip=[address|ID] the IP address or ID of the external NAT entry Optional: commit=[yes|no] commit db transaction (no) EOM ); } // Sanitize "options[commit]" (no is the default) $options['commit'] = sanitize_YN($options['commit'], 'N'); // Find the internal interface list($status, $rows, $interface) = ona_find_interface($options['ip']); if (!$interface['id']) { printmsg("DEBUG => The interface specified, {$options['ip']}, does not exist!", 3); $self['error'] = "ERROR => The interface specified, {$options['ip']}, does not exist!"; return array(2, $self['error'] . "\n"); } printmsg("DEBUG => Interface selected: {$options['ip']}", 3); // Find the NAT interface list($status, $rows, $natinterface) = ona_find_interface($options['natip']); if (!$natinterface['id']) { printmsg("DEBUG => The NAT interface specified, {$options['natip']}, does not exist!", 3); $self['error'] = "ERROR => The NAT interface specified, {$options['natip']}, does not exist!"; return array(3, $self['error'] . "\n"); } printmsg("DEBUG => NAT Interface selected: {$options['natip']}", 3); // Check that the two IP addresses are really paired with each other if ($interface['nat_interface_id'] != $natinterface['id']) { $self['error'] = "ERROR => nat_del() The provided IP addresses are not associated with each other for NAT."; printmsg($self['error'], 0); return array(4, $self['error'] . "\n"); } printmsg("DEBUG => nat_del() calling interface_del() for ip: {$options['natip']}", 3); $natint['interface'] = $natinterface['id']; $natint['commit'] = $options['commit']; list($status, $output) = run_module('interface_del', $natint); if ($status) { return array($status, $output); } $self['error'] .= $output; // update the existing inside interface and remove the old nat_interface_id value list($status, $rows) = db_update_record($onadb, 'interfaces', array('id' => $interface['id']), array('nat_interface_id' => '0')); if ($status or !$rows) { $self['error'] = "ERROR => nat_del() SQL Query failed to update nat_interface_id for interface: " . $self['error']; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => External NAT entry deleted: {$natinterface['ip_addr_text']} from {$interface['ip_addr_text']}."; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
function ws_display_list($window_name, $form = '') { global $conf, $self, $onadb; global $images, $color, $style; $html = ''; $js = ''; // If the user supplied an array in a string, build the array and store it in $form $form = parse_options_string($form); // Find the "tab" we're on $tab = $_SESSION['ona'][$form['form_id']]['tab']; // Build js to refresh this list $refresh = "xajax_window_submit('{$window_name}', xajax.getFormValues('{$form['form_id']}'), 'display_list');"; // Search results go in here $results = array(); $count = 0; // NETWORK ID if (is_numeric($form['subnet_id'])) { } // Do the SQL Query list($status, $count, $results) = db_get_records($onadb, 'interfaces', "subnet_id = " . $onadb->qstr($form['subnet_id']), 'ip_addr', -1, -1); // make an array of ips from our results $iplist = array(); foreach ($results as $record) { $iplist["{$record['ip_addr']}"] = 'used'; } list($status, $rows, $subnet) = ona_find_subnet($form['subnet_id']); // Create a few variables that will be handy later $num_ips = 0xffffffff - $subnet['ip_mask']; $last_ip = $subnet['ip_addr'] + $num_ips - 1; $currip = $subnet['ip_addr'] + 1; // Get a list of blocks that touches this subnet list($status, $blockrows, $blocks) = db_get_records($onadb, 'blocks', "{$subnet['ip_addr']} BETWEEN ip_addr_start AND ip_addr_end OR {$last_ip} BETWEEN ip_addr_start AND ip_addr_end OR ip_addr_start BETWEEN {$subnet['ip_addr']} and {$last_ip}"); // Get a list of dhcp pools on the selected subnet list($status, $rows, $pools) = db_get_records($onadb, 'dhcp_pools', array('subnet_id' => $subnet['id'])); // Add DHCP pool addresses into the list of used ips foreach ($pools as $pool) { for ($ip = $pool['ip_addr_start']; $ip <= $pool['ip_addr_end']; $ip++) { $iplist["{$ip}"] = 'pool-' . $pool['id']; } } // // *** BUILD HTML LIST *** // $html .= <<<EOL <!-- Host Results --> <table id="{$form['form_id']}_full_host_list" class="list-box" cellspacing="0" border="0" cellpadding="0"> <!-- Table Header --> <tr> <td class="list-header" align="center" style="{$style['borderR']};" title="IP Block Association">B</td> <td class="list-header" align="center" style="{$style['borderR']};">IP Address</td> <td class="list-header" align="center" style="{$style['borderR']};">Last Response</td> <td class="list-header" align="center" style="{$style['borderR']};">[Name] Desc</td> <td class="list-header" align="center" style="{$style['borderR']};">Host Name</td> <td class="list-header" align="center" style="{$style['borderR']};">Device Type</td> <td class="list-header" align="center" style="{$style['borderR']};">Host Notes</td> </tr> EOL; // Loop and display each ip on the subnet while ($currip <= $last_ip) { $loc = array(); $host = array(); $interface = array(); $interfaces = 0; $record = array(); $interface_style = ''; $clusterhtml = ''; $rowstyle = 'background-color: #E9FFE1'; $rowid = 'byip_available'; $currip_txt = ip_mangle($currip, 'dotted'); $interface['desc'] = '<span style="color: #aaaaaa;">AVAILABLE</span>'; $nameval = <<<EOL <a title="Add host" class="act" onClick="xajax_window_submit('edit_host', 'ip_addr=>{$currip_txt}', 'editor');" ></a> <a title="Add host" class="act" onClick="xajax_window_submit('edit_host', 'ip_addr=>{$currip_txt}', 'editor');" >Add a new host</a> <a title="Add interface" class="act" onClick="xajax_window_submit('edit_interface', 'ip_addr=>{$currip_txt}', 'editor');" ></a> <a title="Add interface" class="act" onClick="xajax_window_submit('edit_interface', 'ip_addr=>{$currip_txt}', 'editor');" >Add interface to an existing host</a> EOL; // If the current ip is one allocated on this subnet lets do some stuff if (array_key_exists($currip, $iplist)) { $rowid = 'byip_allocated'; $rowstyle = ''; // check if it is a pool range list($pooltype, $poolid) = explode('-', $iplist[$currip]); if ($pooltype == 'pool') { $interface['desc'] = '<span style="color: #aaaaaa;">DHCP Pool</span>'; $rowstyle = 'background-color: #FFFBD6'; $nameval = <<<EOL <a title="Edit Pool" class="act" onClick="xajax_window_submit('edit_dhcp_pool', 'subnet=>{$subnet['id']},id=>{$poolid}', 'editor');" ><img src="{$images}/silk/page_add.png" border="0"></a> <a title="Edit Pool" class="act" onClick="xajax_window_submit('edit_dhcp_pool', 'subnet=>{$subnet['id']},id=>{$poolid}', 'editor');" >Edit DHCP Pool</a> EOL; } else { // Get host record list($status, $rows, $host) = ona_find_host($currip); // Get the interface info list($status, $rows, $interface) = ona_find_interface($currip); // Count how many interface rows this host hasand assign it back to the interfaces variable list($status, $interfaces, $records) = db_get_records($onadb, 'interfaces', 'host_id = ' . $onadb->qstr($host['id']), "", 0); // get interface cluster info list($status, $intclusterrows, $intcluster) = db_get_records($onadb, 'interface_clusters', "interface_id = {$interface['id']}"); if ($intclusterrows > 0) { $clusterscript = "onMouseOver=\"wwTT(this, event,\n 'id', 'tt_interface_cluster_list_{$interface['id']}',\n 'type', 'velcro',\n 'styleClass', 'wwTT_niceTitle',\n 'direction', 'south',\n 'javascript', 'xajax_window_submit(\\'tooltips\\', \\'tooltip=>interface_cluster_list,id=>tt_interface_cluster_list_{$interface['id']},interface_id=>{$interface['id']}\\');'\n );\""; $clusterhtml .= <<<EOL <img src="{$images}/silk/sitemap.png" {$clusterscript} /> EOL; } // set the name value for an allocated host $nameval = <<<EOL <a title="View host. ID: {$host['id']}" class="nav" onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_host\\', \\'host_id=>{$host['id']}\\', \\'display\\')');" >{$host['name']}</a >.<a title="View domain. ID: {$host['domain_id']}" class="domain" onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_domain\\', \\'domain_id=>{$host['domain_id']}\\', \\'display\\')');" >{$host['domain_fqdn']}</a> EOL; // Make it bold if we have more than one interface on this host if ($interfaces > 1) { $interface_style = 'font-weight: bold;'; } // Device Description list($status, $rows, $device) = ona_find_device($host['device_id']); list($status, $rows, $device_type) = ona_get_device_type_record(array('id' => $device['device_type_id'])); list($status, $rows, $role) = ona_get_role_record(array('id' => $device_type['role_id'])); list($status, $rows, $model) = ona_get_model_record(array('id' => $device_type['model_id'])); list($status, $rows, $manufacturer) = ona_get_manufacturer_record(array('id' => $model['manufacturer_id'])); $record['device'] = "{$manufacturer['name']}, {$model['name']} ({$role['name']})"; $record['device'] = str_replace('Unknown', '?', $record['device']); $record['notes_short'] = truncate($host['notes'], 40); $interface['description_short'] = truncate($interface['description'], 40); if ($interface['name']) { $interface['name'] = "[{$interface['name']}]"; } $interface['desc'] = "{$interface['name']} {$interface['description_short']}"; // Format the date and colorize if its older than 2 months if ($interface['last_response']) { $interface['last_response'] = date($conf['date_format'], strtotime($interface['last_response'])); if (strtotime($interface['last_response']) < strtotime('-2 month')) { $interface['last_response_fmt'] = 'style=color:red;'; } } // Get location info list($status, $rows, $loc) = ona_get_location_record(array('id' => $device['location_id'])); } // end real host ifblock } // end while loop // Escape data for display in html foreach (array_keys($record) as $key) { $record[$key] = htmlentities($record[$key], ENT_QUOTES, $conf['php_charset']); } $html .= <<<EOL <tr {$rowid}=true style="{$rowstyle}" onMouseOver="this.className='row-highlight'" onMouseOut="this.className='row-normal'"> EOL; // Print color info for any matching blocks $c = 0; $blockcolors = array('#CD5C5C', '#588C7E', '#8C4646', '#FFD700', '#1E90F0', '#8A2BE2', '#32CD32', '#D96459'); if ($blockrows) { $html .= "<td class='list-row' nowrap style='padding:0'>"; foreach ($blocks as $block) { if ($currip >= $block['ip_addr_start'] && $currip <= $block['ip_addr_end']) { $html .= "<span title='{$block['name']}' style='background-color:{$blockcolors[$c]};padding-bottom:4px;float:left;'>  </span> "; } $c++; } } else { // print an empty table cell $html .= "<td class='list-row'>"; } $html .= <<<EOL </td> <td class="list-row" align="left"> EOL; // if it is used, show an edit interface link if ($rowid == 'byip_allocated') { $html .= <<<EOL <a class="nav" style="{$interface_style}" title="Edit interface ID: {$interface['id']}" onClick="xajax_window_submit('edit_interface', 'interface_id=>{$interface['id']}', 'editor');" EOL; if ($interfaces > 1) { $html .= <<<EOL onMouseOver="wwTT(this, event, 'id', 'tt_host_interface_list_{$host['id']}', 'type', 'velcro', 'styleClass', 'wwTT_niceTitle', 'direction', 'south', 'javascript', 'xajax_window_submit(\\'tooltips\\', \\'tooltip=>host_interface_list,id=>tt_host_interface_list_{$host['id']},host_id=>{$host['id']}\\');' );" EOL; } $html .= '>'; } //print out the IP address $html .= $currip_txt; // close the A tag if used above if ($rowid == 'byip_allocated') { $html .= '</a>'; } // Keep on goin with the rest of the line $html .= <<<EOL <span>{$clusterhtml}</span> </td> <td class="list-row" {$interface['last_response_fmt']}>{$interface['last_response']} </td> <td class="list-row"> <span title="{$interface['description']}">{$interface['desc']}</span> </td> <td class="list-row" style="border-left: 1px solid; border-left-color: #aaaaaa;"> {$nameval} </td> <td class="list-row">{$record['device']} </td> <td class="list-row"> <span title="{$host['notes']}">{$record['notes_short']}</span> </td> </tr> EOL; // increment the currip $currip++; } $html .= <<<EOL </table> EOL; $js .= <<<EOL /* Make sure this table is 100% wide */ el('{$form['form_id']}_full_host_list').style.width = el('{$form['form_id']}_table').offsetWidth + 'px'; function togglebyip(name) { tr=document.getElementsByTagName('tr') for (i=0;i<tr.length;i++){ if (tr[i].getAttribute(name)){ if (tr[i].style.display=='none'){tr[i].style.display = '';} else {tr[i].style.display = 'none';} } } } EOL; // Insert the new html into the content div specified // Instantiate the xajaxResponse object $response = new xajaxResponse(); $response->addAssign("{$form['form_id']}_{$tab}_count", "innerHTML", "({$count})"); $response->addAssign($form['content_id'], "innerHTML", $html); if ($js) { $response->addScript($js); } return $response->getXML(); }