Example #1
0
function ws_interface_nat_save($window_name, $form = '')
{
    global $base, $include, $conf, $self, $onadb;
    // Check permissions
    if (!auth('interface_modify')) {
        $response = new xajaxResponse();
        $response->addScript("alert('Permission denied!');");
        return $response->getXML();
    }
    $form = parse_options_string($form);
    // Instantiate the xajaxResponse object
    $response = new xajaxResponse();
    $js = '';
    $refresh = "xajax_window_submit('list_interfaces', xajax.getFormValues('list_interfaces_filter_form'), 'display_list');";
    // Validate input
    if (!$form['ip'] and !$form['natip']) {
        $response->addScript("alert('Please complete all fields to continue!');");
        return $response->getXML();
    }
    // Decide if we're deleting or adding
    $module = 'nat_add';
    if ($form['nataction'] == "delete") {
        $module = 'nat_del';
    }
    // Do a pre check of the ptr domain so we can prompt the user properly
    if ($module == 'nat_add') {
        $ipflip = ip_mangle($form['natip'], 'flip');
        $octets = explode(".", $ipflip);
        list($status, $rows, $ptrdomain) = ona_find_domain($ipflip . ".in-addr.arpa");
        if (!$ptrdomain['id']) {
            printmsg("ERROR => This operation tried to create a PTR record that is the first in the {$octets[3]}.0.0.0 class A range.  You must first create at least the following DNS domain: {$octets[3]}.in-addr.arpa", 3);
            $self['error'] = "ERROR => This operation tried to create a PTR record that is the first in the {$octets[3]}.0.0.0 class A range.  You must first create at least the following DNS domain: {$octets[3]}.in-addr.arpa.  You could also create domains for class B or class C level reverse zones.  Click OK to open add domain dialog";
            $response->addScript("alert('{$self['error']}');xajax_window_submit('edit_domain', 'newptrdomainname=>{$octets[3]}.in-addr.arpa', 'editor');");
            return $response->getXML();
        }
    }
    // Run the module
    list($status, $output) = run_module($module, $form);
    // If the module returned an error code display a popup warning
    if ($status) {
        $js .= "alert('Save failed. " . preg_replace('/[\\s\']+/', ' ', $self['error']) . "');";
    } else {
        $js .= "removeElement('{$window_name}');{$refresh}";
        if ($form['js']) {
            $js .= $form['js'];
        }
    }
    // Insert the new table into the window
    $response->addScript($js);
    return $response->getXML();
}
Example #2
0
function ona_find_dns_record($search = "", $type = '', $int_id = 0)
{
    global $conf, $self, $onadb;
    printmsg("DEBUG => ona_find_dns_record({$search}) called", 3);
    $type = strtoupper($type);
    $search = strtolower($search);
    // By record ID?
    if (is_numeric($search)) {
        list($status, $rows, $dns) = ona_get_dns_record(array('id' => $search));
        if ($rows) {
            printmsg("DEBUG => ona_find_dns_record({$search}) called, found: {$dns['fqdn']}({$dns['type']})", 3);
            return array($status, $rows, $dns);
        }
    }
    //
    // 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)));
        if (!$rows) {
            $view['id'] = 0;
        }
    }
    // Find the domain name piece of $search
    list($status, $rows, $domain) = ona_find_domain($search);
    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);
    // 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 = '';
    }
    // Setup the search array
    $searcharray = array('domain_id' => $domain['id'], 'name' => $hostname, 'dns_view_id' => $view['id']);
    // If an interface_id was passed, add it to the array
    if ($int_id > 0) {
        $searcharray['interface_id'] = $int_id;
    }
    // If a type was passed, add it to the array
    if ($type) {
        $searcharray['type'] = $type;
    }
    // Let's see if that hostname is valid or not in $domain['id']
    list($status, $rows, $dns) = ona_get_dns_record($searcharray);
    if ($rows) {
        // Return good status, one row, and $dns array
        printmsg("DEBUG => ona_find_dns_record({$search}) called, found: {$dns['fqdn']}({$dns['type']})", 3);
        return array(0, 1, $dns);
    }
    // Otherwise, build a fake dns record with only a few entries in it and return that
    $dns = array('id' => 0, 'name' => $hostname, 'fqdn' => "{$hostname}.{$domain['fqdn']}", 'domain_id' => $domain['id'], 'domain_fqdn' => $domain['fqdn'], 'type' => '', 'dns_id' => 0);
    printmsg("DEBUG => ona_find_dns_record({$search}) called, Nothing found, returning fake entry: {$dns['fqdn']}({$dns['type']})", 3);
    return array(0, 1, $dns);
}
Example #3
0
function ws_save($window_name, $form = '')
{
    global $include, $conf, $self, $onadb;
    // Check permissions
    if (!(auth('host_modify') or auth('host_add'))) {
        $response = new xajaxResponse();
        $response->addScript("alert('Permission denied!');");
        return $response->getXML();
    }
    // Instantiate the xajaxResponse object
    $response = new xajaxResponse();
    $js = '';
    // Validate input
    if ($form['set_type'] == '' or $form['host'] == '.' and $form['set_ip'] == '') {
        $response->addScript("alert('Please complete all fields to continue!');");
        return $response->getXML();
    }
    // Since we're adding two records (host and an interface)
    // we need to do a little validation here to make sure things
    // have a good chance of working!
    // Validate the "set_host" name is valid
    $form['set_host'] = sanitize_hostname(trim($form['set_host']));
    if (!$form['set_host']) {
        $response->addScript("alert('Invalid hostname!');");
        return $response->getXML();
    }
    // Validate domain is valid
    //     list($status, $rows, $domain) = ona_find_domain($form['set_domain'],0);
    //     if ($status or !$rows) {
    //         $response->addScript("alert('Invalid domain!');");
    //         return($response->getXML());
    //     }
    // Make sure the IP address specified is valid
    if ($form['host'] != '.' and $form['set_ip']) {
        $form['set_ip'] = ip_mangle($form['set_ip'], 'dotted');
        if ($form['set_ip'] == -1) {
            $response->addScript("alert('{$self['error']}');");
            return $response->getXML();
        }
    }
    if ($form['set_addptr'] == '') {
        $form['set_addptr'] = 'N';
    }
    // FIXME: If we're editing, validate the $form['host'] is valid
    // FIXME: If we're editing, validate the $form['interface'] is valid
    // FIXME: Verify that the device "type" ID is valid (not a big risk since they select from a drop-down)
    // If no location is passed, make sure the value is 0
    // if (array_key_exists('set_location', $form)) $form['set_location'] = 0;
    // Decide if we're editing or adding
    $module = 'modify';
    // If we're adding, re-map some the array names to match what the "add" module wants
    if ($form['host'] == '.') {
        $module = 'add';
        if (!auth('host_add')) {
            $response = new xajaxResponse();
            $response->addScript("alert('Permission denied!');");
            return $response->getXML();
        }
        // Device options
        $form['type'] = $form['set_type'];
        unset($form['set_type']);
        $form['location'] = $form['set_location'];
        unset($form['set_location']);
        // Host options
        $form['domain'] = $form['set_domain'];
        $form['host'] = $form['set_host'] . '.' . $form['set_domain'];
        unset($form['set_host']);
        unset($form['set_domain']);
        $form['notes'] = $form['set_notes'];
        unset($form['set_notes']);
        $form['description'] = $form['set_description'];
        unset($form['set_description']);
        $form['view'] = $form['set_view'];
        unset($form['set_view']);
        // Interface options
        $form['ip'] = $form['set_ip'];
        unset($form['set_ip']);
        $form['mac'] = $form['set_mac'];
        unset($form['set_mac']);
        $form['name'] = $form['set_name'];
        unset($form['set_name']);
        $form['addptr'] = $form['set_addptr'];
        unset($form['set_addptr']);
        // If there's no "refresh" javascript, add a command to view the new host
        if (!preg_match('/\\w/', $form['js'])) {
            $form['js'] = "xajax_window_submit('work_space', 'xajax_window_submit(\\'display_host\\', \\'host=>{$form['host']}\\', \\'display\\')');";
        }
    } else {
        $form['set_host'] .= '.' . $form['set_domain'];
    }
    // Do a pre check of the ptr domain so we can prompt the user properly
    if ($module == 'add') {
        $ipflip = ip_mangle($form['ip'], 'flip');
        $octets = explode(".", $ipflip);
        if (count($octets) > 4) {
            $arpa = '.ip6.arpa';
            $octcount = 31;
        } else {
            $arpa = '.in-addr.arpa';
            $octcount = 3;
        }
        list($status, $rows, $ptrdomain) = ona_find_domain($ipflip . $arpa);
        if (!$ptrdomain['id']) {
            printmsg("ERROR => This operation tried to create a PTR record that is the first in this IP address space.  You must first create at least the following DNS domain: {$octets[$octcount]}.in-addr.arpa", 3);
            $self['error'] = "ERROR => This operation tried to create a PTR record that is the first in this IP address space.<br>You must first create at least the following DNS domain: <b>{$octets[$octcount]}.in-addr.arpa</b>.<br>You could also create domains at deeper level reverse zones if desired.<br>We have opened the add domain dialog for you.";
            $response->addScript("alert('{$self['error']}');xajax_window_submit('edit_domain', 'newptrdomainname=>{$octets[$octcount]}{$arpa}', 'editor');");
            return $response->getXML();
        }
    }
    // Run the module to ADD the HOST AND INTERFACE, or MODIFY THE HOST.
    list($status, $output) = run_module('host_' . $module, $form);
    // If the module returned an error code display a popup warning
    if ($status) {
        $js .= "alert('Save failed.\\n" . preg_replace('/[\\s\']+/', ' ', $self['error']) . "');";
    } else {
        // Run the module to MODIFY THE INTERFACE if we need to
        if ($module == 'modify' and $form['set_ip']) {
            list($status, $output) = run_module('interface_' . $module, $form);
        }
        // If the module returned an error code display a popup warning
        if ($status and $module == 'modify' and $form['set_ip']) {
            $js .= "alert('Interface update failed.\\n" . preg_replace('/[\\s\']+/', ' ', $self['error']) . "');";
        } else {
            // if they have checked the keep adding hosts box then dont remove the window
            if (!$form['keepadding']) {
                $js .= "removeElement('{$window_name}');";
            } else {
                $js .= "el('statusinfo_{$window_name}').innerHTML = 'Previously added:<br>{$form['host']} => {$form['ip']}';";
            }
            if ($form['js']) {
                $js .= $form['js'];
            }
        }
    }
    // Insert the new table into the window
    $response->addScript($js);
    return $response->getXML();
}
Example #4
0
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");
}
Example #5
0
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");
}
Example #6
0
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, transform it into an array
    $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');";
    // If it's not a new query, load the previous query from the session
    // into $form and save the current page and filter in the session.
    // Also find/set the "page" we're viewing
    $page = 1;
    if ($form['page'] and is_numeric($form['page'])) {
        $form = array_merge($form, (array) $_SESSION['ona'][$form['form_id']][$tab]['q']);
        $_SESSION['ona'][$form['form_id']][$tab]['page'] = $page = $form['page'];
        $_SESSION['ona'][$form['form_id']][$tab]['filter'] = $form['filter'];
    }
    printmsg("DEBUG => Displaying records list page: {$page}", 1);
    // Calculate the SQL query offset (based on the page being displayed)
    $offset = $conf['search_results_per_page'] * ($page - 1);
    if ($offset == 0) {
        $offset = -1;
    }
    // Search results go in here
    $results = array();
    $count = 0;
    //
    // *** ADVANCED RECORD SEARCH ***
    //       FIND RESULT SET
    //
    // Start building the "where" clause for the sql query to find the records to display
    $where = "";
    $and = "";
    $orderby = "";
    // enable or disable wildcards
    $wildcard = '%';
    if ($form['nowildcard']) {
        $wildcard = '';
    }
    // RECORD ID
    if ($form['record_id']) {
        $where .= $and . "id = " . $onadb->qstr($form['record_id']);
        $and = " AND ";
    }
    // DNS VIEW ID
    if ($form['dns_view']) {
        if (is_string($form['dns_view'])) {
            list($status, $rows, $dnsview) = ona_get_dns_view_record(array('name' => $form['dns_view']));
        }
        if (is_numeric($form['dns_view'])) {
            list($status, $rows, $dnsview) = ona_get_dns_view_record(array('id' => $form['dns_view']));
        }
        $where .= $and . "dns_view_id = " . $onadb->qstr($dnsview['id']);
        $and = " AND ";
    }
    // INTERFACE ID
    if ($form['interface_id']) {
        $where .= $and . "interface_id = " . $onadb->qstr($form['interface_id']);
        $and = " AND ";
    }
    // DNS RECORD note
    if ($form['notes']) {
        $where .= $and . "notes LIKE " . $onadb->qstr($wildcard . $form['notes'] . $wildcard);
        $and = " AND ";
    }
    // DNS RECORD TYPE
    if ($form['dnstype']) {
        $where .= $and . "type = " . $onadb->qstr($form['dnstype']);
        $and = " AND ";
    }
    // HOSTNAME
    if ($form['hostname']) {
        $where .= $and . "id IN (SELECT id " . "  FROM dns " . "  WHERE name LIKE " . $onadb->qstr($wildcard . $form['hostname'] . $wildcard) . " )";
        $and = " AND ";
    }
    // DOMAIN
    if ($form['domain']) {
        // FIXME: MP test if this clause works correctly?  Not sure that anything even uses this?
        list($status, $rows, $tmpdomain) = ona_find_domain($form['domain']);
        $where .= $and . "domain_id = " . $onadb->qstr($tmpdomain['id']);
        $orderby .= "name, domain_id";
        $and = " AND ";
    }
    // DOMAIN ID
    if ($form['domain_id']) {
        //$where .= $and . "primary_dns_id IN ( SELECT id " .
        //                                    "  FROM dns " .
        //                                    "  WHERE domain_id = " . $onadb->qstr($form['domain_id']) . " )  ";
        $where .= $and . "domain_id = " . $onadb->qstr($form['domain_id']);
        $orderby .= "name, domain_id";
        $and = " AND ";
    }
    // IP ADDRESS
    $ip = $ip_end = '';
    if ($form['ip']) {
        // Build $ip and $ip_end from $form['ip'] and $form['ip_thru']
        $ip = ip_complete($form['ip'], '0');
        if ($form['ip_thru']) {
            $ip_end = ip_complete($form['ip_thru'], '255');
        } else {
            $ip_end = ip_complete($form['ip'], '255');
        }
        // Find out if $ip and $ip_end are valid
        $ip = ip_mangle($ip, 'numeric');
        $ip_end = ip_mangle($ip_end, 'numeric');
        if ($ip != -1 and $ip_end != -1) {
            // We do a sub-select to find interface id's between the specified ranges
            $where .= $and . "interface_id IN ( SELECT id " . "        FROM interfaces " . "        WHERE ip_addr >= " . $onadb->qstr($ip) . " AND ip_addr <= " . $onadb->qstr($ip_end) . " )";
            $and = " AND ";
        }
    }
    // display a nice message when we dont find all the records
    if ($where == '' and $form['content_id'] == 'search_results_list') {
        $js .= "el('search_results_msg').innerHTML = 'Unable to find DNS records matching your query, showing all records';";
    }
    // Wild card .. if $while is still empty, add a 'ID > 0' to it so you see everything.
    if ($where == '') {
        $where = 'id > 0';
    }
    // If we dont have DNS views turned on, limit data to just the default view.
    // Even if there is data associated with other views, ignore it
    if (!$conf['dns_views']) {
        $where .= ' AND dns_view_id = 0';
    }
    // Do the SQL Query
    $filter = '';
    if ($form['filter']) {
        // Host names should always be lower case
        $form['filter'] = strtolower($form['filter']);
        $filter = ' AND name LIKE ' . $onadb->qstr('%' . $form['filter'] . '%');
    }
    // If we get a specific host to look for we must do the following
    // 1. get (A) records that match any interface_id associated with the host
    // 2. get CNAMES that point to dns records that are using an interface_id associated with the host
    if ($form['host_id']) {
        // If we dont have DNS views turned on, limit data to just the default view.
        // Even if there is data associated with other views, ignore it
        // MP: something strange with this, it should only limit to default view.. sometimes it does not???
        if (!$conf['dns_views']) {
            $hwhere .= 'dns_view_id = 0 AND ';
        }
        // Get the host record so we know what the primary interface is
        list($status, $rows, $host) = ona_get_host_record(array('id' => $form['host_id']), '');
        list($status, $rows, $results) = db_get_records($onadb, 'dns', $hwhere . 'interface_id in (select id from interfaces where host_id = ' . $onadb->qstr($form['host_id']) . ') OR interface_id in (select interface_id from interface_clusters where host_id = ' . $onadb->qstr($form['host_id']) . ')', "type", $conf['search_results_per_page'], $offset);
        // If we got less than search_results_per_page, add the current offset to it
        // so that if we're on the last page $rows still has the right number in it.
        if ($rows > 0 and $rows < $conf['search_results_per_page']) {
            $rows += $conf['search_results_per_page'] * ($page - 1);
        } else {
            if ($rows >= $conf['search_results_per_page']) {
                list($status, $rows, $records) = db_get_records($onadb, 'dns', $hwhere . 'interface_id in (select id from interfaces where host_id = ' . $onadb->qstr($form['host_id']) . ') OR interface_id in (select interface_id from interface_clusters where host_id = ' . $onadb->qstr($form['host_id']) . ')' . $filter, "", 0);
            }
        }
    } else {
        list($status, $rows, $results) = db_get_records($onadb, 'dns', $where . $filter, $orderby, $conf['search_results_per_page'], $offset);
        // If we got less than search_results_per_page, add the current offset to it
        // so that if we're on the last page $rows still has the right number in it.
        if ($rows > 0 and $rows < $conf['search_results_per_page']) {
            $rows += $conf['search_results_per_page'] * ($page - 1);
        } else {
            if ($rows >= $conf['search_results_per_page']) {
                list($status, $rows, $records) = db_get_records($onadb, 'dns', $where . $filter, "", 0);
            }
        }
    }
    $count = $rows;
    //
    // *** BUILD HTML LIST ***
    //
    $html .= <<<EOL
        <!-- dns record Results -->
        <table id="{$form['form_id']}_dns_record_list" class="list-box" cellspacing="0" border="0" cellpadding="0">

            <!-- Table Header -->
            <tr>

                <td colspan="2" class="list-header" align="center" style="{$style['borderR']};">Name</td>
                <td class="list-header" align="center" style="{$style['borderR']};">Time to Live</td>
                <td class="list-header" align="center" style="{$style['borderR']};">Type</td>
                <td class="list-header" align="center" style="{$style['borderR']};">Data</td>
                <td class="list-header" align="center" style="{$style['borderR']};">Effective</td>
EOL;
    if ($conf['dns_views']) {
        $html .= "<td class=\"list-header\" align=\"center\" style=\"{$style['borderR']};\">DNS View</td>";
    }
    $html .= <<<EOL
                <td class="list-header" align="center" style="{$style['borderR']};">Notes</td>
                <td class="list-header" align="center">&nbsp;</td>
            </tr>
EOL;
    // Loop and display each record
    //  $last_record = array('name' => $results[0]['name'], 'domain_id' => $results[0]['domain_id']);
    //  $last_record_count = 0;
    for ($i = 1; $i <= count($results); $i++) {
        $record = $results[$i];
        // Get additional info about each host record
        $record = $results[$i - 1];
        // if the interface is the primary_dns_id for the host then mark it
        $primary_record = '&nbsp;';
        if ($host['primary_dns_id'] == $record['id']) {
            $primary_record = '<img title="Primary DNS record" src="' . $images . '/silk/font_go.png" border="0">';
        }
        // Check for interface records (and find out how many there are)
        list($status, $interfaces, $interface) = ona_get_interface_record(array('id' => $record['interface_id']), '');
        if ($interfaces) {
            // Get the host record so we know what the primary interface is
            //list($status, $rows, $inthost) = ona_get_host_record(array('id' => $interface['host_id']), '');
            // Make the type correct based on the IP passed in
            if (strlen($interface['ip_addr']) > 11 and $record['type'] == 'A') {
                $record['type'] = 'AAAA';
            }
            $record['ip_addr'] = ip_mangle($interface['ip_addr'], 'dotted');
            // Subnet description
            list($status, $rows, $subnet) = ona_get_subnet_record(array('id' => $interface['subnet_id']));
            $record['subnet'] = $subnet['name'];
            $record['ip_mask'] = ip_mangle($subnet['ip_mask'], 'dotted');
            $record['ip_mask_cidr'] = ip_mangle($subnet['ip_mask'], 'cidr');
            // Create string to be embedded in HTML for display
            $data = <<<EOL
                        {$record['ip_addr']}&nbsp;

EOL;
        } else {
            // Get other DNS records which name this record as parent
            list($status, $rows, $dns_other) = ona_get_host_record(array('id' => $record['dns_id']));
            // Create string to be embedded in HTML for display
            if ($rows) {
                $data = <<<EOL
                <a title="View host. ID: {$dns_other['id']}"
                    class="nav"
                    onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_host\\', \\'host_id=>{$dns_other['id']}\\', \\'display\\')');"
                >{$dns_other['name']}</a
                >.<a title="View domain. ID: {$dns_other['domain_id']}"
                        class="domain"
                        onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_domain\\', \\'domain_id=>{$dns_other['domain_id']}\\', \\'display\\')');"
                >{$dns_other['domain_fqdn']}</a>&nbsp;
EOL;
            }
        }
        $record['notes_short'] = truncate($record['notes'], 30);
        // Add a dot to the end of record name for display purposes
        $record['name'] = $record['name'] . '.';
        // Process PTR record
        if ($record['type'] == 'PTR') {
            list($status, $rows, $pointsto) = ona_get_dns_record(array('id' => $record['dns_id']), '');
            list($status, $rows, $pdomain) = ona_get_domain_record(array('id' => $record['domain_id']), '');
            // Flip the IP address
            $record['name'] = ip_mangle($record['ip_addr'], 'flip');
            $record['domain'] = $pdomain['name'];
            if ($pdomain['parent_id']) {
                list($status, $rows, $parent) = ona_get_domain_record(array('id' => $pdomain['parent_id']));
                $parent['name'] = ona_build_domain_name($parent['id']);
                $record['domain'] = $pdomain['name'] . '.' . $parent['name'];
                unset($parent['name']);
            }
            // strip down the IP to just the "host" part as it relates to the domain its in
            if (strstr($record['domain'], 'in-addr.arpa')) {
                $domain_part = preg_replace("/.in-addr.arpa\$/", '', $record['domain']);
            } else {
                $domain_part = preg_replace("/.ip6.arpa\$/", '', $record['domain']);
            }
            $record['name'] = preg_replace("/{$domain_part}\$/", '', $record['name']);
            $data = <<<EOL
                    <a title="Edit DNS A record"
                       class="act"
                       onClick="xajax_window_submit('edit_record', 'dns_record_id=>{$record['dns_id']}', 'editor');"
                    >{$pointsto['name']}</a>.<a title="View domain. ID: {$pointsto['domain_id']}"
                         class="domain"
                         onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_domain\\', \\'domain_id=>{$pointsto['domain_id']}\\', \\'display\\')');"
                    >{$pointsto['domain_fqdn']}</a>.&nbsp;
EOL;
        }
        // Process CNAME record
        if ($record['type'] == 'CNAME') {
            list($status, $rows, $cname) = ona_get_dns_record(array('id' => $record['dns_id']), '');
            $data = <<<EOL
                    <a title="Edit DNS A record"
                       class="act"
                       onClick="xajax_window_submit('edit_record', 'dns_record_id=>{$record['dns_id']}', 'editor');"
                    >{$cname['name']}</a>.<a title="View domain. ID: {$cname['domain_id']}"
                         class="domain"
                         onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_domain\\', \\'domain_id=>{$cname['domain_id']}\\', \\'display\\')');"
                    >{$cname['domain_fqdn']}</a>.&nbsp;
EOL;
        }
        // Process NS record
        if ($record['type'] == 'NS') {
            // clear out the $record['domain'] value so it shows properly in the list
            $record['name'] = '';
            list($status, $rows, $ns) = ona_get_dns_record(array('id' => $record['dns_id']), '');
            $data = <<<EOL
                    <a title="Edit DNS A record"
                       class="act"
                       onClick="xajax_window_submit('edit_record', 'dns_record_id=>{$record['dns_id']}', 'editor');"
                    >{$ns['name']}</a>.<a title="View domain. ID: {$ns['domain_id']}"
                         class="domain"
                         onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_domain\\', \\'domain_id=>{$ns['domain_id']}\\', \\'display\\')');"
                    >{$ns['domain_fqdn']}</a>.&nbsp;
EOL;
        }
        // Process MX record
        if ($record['type'] == 'MX') {
            // show the preference value next to the type
            $record['type'] = "{$record['type']} ({$record['mx_preference']})";
            list($status, $rows, $mx) = ona_get_dns_record(array('id' => $record['dns_id']), '');
            $data = <<<EOL
                    <a title="Edit DNS A record"
                       class="act"
                       onClick="xajax_window_submit('edit_record', 'dns_record_id=>{$record['dns_id']}', 'editor');"
                    >{$mx['name']}</a>.<a title="View domain. ID: {$mx['domain_id']}"
                         class="domain"
                         onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_domain\\', \\'domain_id=>{$mx['domain_id']}\\', \\'display\\')');"
                    >{$mx['domain_fqdn']}</a>.&nbsp;
EOL;
        }
        // Process SRV record
        if ($record['type'] == 'SRV') {
            // show the preference value next to the type
            $record['type'] = "{$record['type']} ({$record['srv_port']})";
            list($status, $rows, $srv) = ona_get_dns_record(array('id' => $record['dns_id']), '');
            $data = <<<EOL
                    <a title="Edit DNS A record"
                       class="act"
                       onClick="xajax_window_submit('edit_record', 'dns_record_id=>{$record['dns_id']}', 'editor');"
                    >{$srv['name']}</a>.<a title="View domain. ID: {$srv['domain_id']}"
                         class="domain"
                         onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_domain\\', \\'domain_id=>{$srv['domain_id']}\\', \\'display\\')');"
                    >{$srv['domain_fqdn']}</a>.&nbsp;
EOL;
        }
        // Process TXT record
        if ($record['type'] == 'TXT') {
            // some records will have an interfaceid and dnsid when associated to another dns name
            // some will just be un associated txt records or domain only records.  Determine that here and
            // display appropriately.  This is to ensure associated DNS records match up if the name changes
            if ($record['interface_id'] and $record['dns_id']) {
                list($status, $rows, $txtmain) = ona_get_dns_record(array('id' => $record['dns_id']), '');
                $record['name'] = $txtmain['name'] . '.';
            }
            $data = truncate($record['txt'], 70);
        }
        // Get the domain name and domain ttl
        $ttl_style = 'title="Time-to-Live"';
        list($status, $rows, $domain) = ona_get_domain_record(array('id' => $record['domain_id']));
        // Make record['domain'] have the right name in it
        if ($record['type'] != 'PTR') {
            $record['domain'] = $domain['fqdn'];
        }
        // clear out the $record['domain'] value so it shows properly in the list for NS records
        if ($record['type'] == 'NS') {
            $record['domain'] = $domain['fqdn'];
        }
        // if the ttl is blank, use the one in the domain (minimum)
        if ($record['ttl'] == 0) {
            $record['ttl'] = $domain['default_ttl'];
            $ttl_style = 'style="font-style: italic;" title="Using TTL from domain"';
        }
        // format the ebegin using the configured date format
        $ebegin = '';
        // If it is in the future, print the time
        if (strtotime($record['ebegin']) > time()) {
            $ebegin = '<span title="Active in DNS on: ' . $record['ebegin'] . '">' . date($conf['date_format'], strtotime($record['ebegin'])) . '</span>';
        }
        // If it is 0 then show as disabled
        if (strtotime($record['ebegin']) < 0) {
            $ebegin = <<<EOL
                <span
                    style="background-color:#FFFF99;"
                    title="Disabled: Won't build in DNS"
                    onClick="var doit=confirm('Are you sure you want to enable this DNS record?');
                                if (doit == true)
                                    xajax_window_submit('edit_record', xajax.getFormValues('{$form['form_id']}_list_record_{$record['id']}'), 'enablerecord');"
                >Disabled</span>
EOL;
        }
        // If we get this far and the name we have built has a leading . in it then remove the dot.
        $record['name'] = preg_replace("/^\\./", '', $record['name']);
        // Get the name of the view and the description
        if ($conf['dns_views']) {
            list($status, $rows, $dnsview) = ona_get_dns_view_record(array('id' => $record['dns_view_id']));
            $record['view_name'] = $dnsview['name'];
            $record['view_desc'] = $dnsview['description'];
        }
        // Escape data for display in html
        foreach (array_keys($record) as $key) {
            $record[$key] = htmlentities($record[$key], ENT_QUOTES, $conf['php_charset']);
        }
        //$primary_object_js = "xajax_window_submit('work_space', 'xajax_window_submit(\'display_host\', \'host_id=>{$record['id']}\', \'display\')');";
        $html .= <<<EOL
            <tr onMouseOver="this.className='row-highlight';" onMouseOut="this.className='row-normal';">
                <td class="list-row" style="padding-right: 2px; padding-left: 4px;" width="16px">
                {$primary_record}
                </td>

                <td class="list-row">
                    <span title="Record. ID: {$record['id']}"
                       onClick=""
                    >{$record['name']}</span
                    ><a title="View domain. ID: {$domain['id']}"
                         class="domain"
                         onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_domain\\', \\'domain_id=>{$domain['id']}\\', \\'display\\')');"
                    >{$record['domain']}.</a>
                </td>

                <td class="list-row">
                    <span
                       onClick=""
                       {$ttl_style}
                    >{$record['ttl']} seconds</span>&nbsp;
                </td>

                <td class="list-row">
                    <span title="Record Type"
                       onClick=""
                    >{$record['type']}</span>&nbsp;
                </td>

                <td class="list-row" align="left">
EOL;
        // Put the data in!
        $html .= $data;
        $html .= <<<EOL
                </td>

                <td class="list-row" align="center">
                    {$ebegin}&nbsp;
                </td>
EOL;
        // Display the view we are part of
        if ($conf['dns_views']) {
            $html .= <<<EOL
                <td class="list-row" align="center" title="{$record['view_desc']}">
                    {$record['view_name']}&nbsp;
                </td>
EOL;
        }
        $html .= <<<EOL
                <td class="list-row">
                    <span title="{$record['notes']}">{$record['notes_short']}</span>&nbsp;
                </td>

                <!-- ACTION ICONS -->
                <td class="list-row" align="right">
                    <form id="{$form['form_id']}_list_record_{$record['id']}"
                        ><input type="hidden" name="dns_record_id" value="{$record['id']}"
                        ><input type="hidden" name="host_id" value="{$host['id']}"
                        ><input type="hidden" name="js" value="{$refresh}"
                    ></form>&nbsp;
EOL;
        if (auth('dns_record_modify')) {
            // If it is an A record but not the primary, display an option to make it primary. and only if we are dealing with a specific host
            if (($record['type'] == 'A' or $record['type'] == 'AAAA') and $host['primary_dns_id'] != $record['id'] and $form['host_id']) {
                $html .= <<<EOL

                    <a title="Make this the primary DNS record"
                       class="act"
                       onClick="var doit=confirm('Are you sure you want to make this the primary DNS record for this host?');
                                if (doit == true)
                                    xajax_window_submit('edit_record', xajax.getFormValues('{$form['form_id']}_list_record_{$record['id']}'), 'makeprimary');"
                    ><img src="{$images}/silk/font_go.png" border="0"></a>
EOL;
            }
        }
        // display a view host button on the dns record search form list
        if ($form['search_form_id'] == 'dns_record_search_form') {
            $html .= <<<EOL

                    <a title="View associated host record: {$interface['host_id']}"
                       class="act"
                       onClick="xajax_window_submit('display_host', 'host_id=>{$interface['host_id']}', 'display');"
                    ><img src="{$images}/silk/computer_go.png" border="0"></a>&nbsp;
EOL;
        }
        if (auth('dns_record_modify')) {
            $html .= <<<EOL

                    <a title="Edit DNS record"
                       class="act"
                       onClick="xajax_window_submit('edit_record', xajax.getFormValues('{$form['form_id']}_list_record_{$record['id']}'), 'editor');"
                    ><img src="{$images}/silk/page_edit.png" border="0"></a>&nbsp;
EOL;
        }
        if (auth('dns_record_del')) {
            $html .= <<<EOL

                    <a title="Delete DNS record"
                       class="act"
                       onClick="xajax_window_submit('edit_record', xajax.getFormValues('{$form['form_id']}_list_record_{$record['id']}'), 'delete');"
                    ><img src="{$images}/silk/delete.png" border="0"></a>
EOL;
        }
        $html .= <<<EOL
                    &nbsp;
                </td>

            </tr>
EOL;
        // reset the record counter before we go back for the next iteration
        $last_record = array('name' => $record['name'], 'domain_id' => $record['domain_id']);
        $last_record_count = 1;
    }
    $html .= <<<EOL
    </table>
EOL;
    // Build page links if there are any
    $html .= get_page_links($page, $conf['search_results_per_page'], $count, $window_name, $form['form_id']);
    // 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();
}
Example #7
0
function host_add($options = "")
{
    global $conf, $self, $onadb;
    // Version - UPDATE on every edit!
    $version = '1.11';
    printmsg("DEBUG => host_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['host'] and $options['type'] 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

host_add-v{$version}
Add a new host

  Synopsis: host_add [KEY=VALUE] ...

  Required:
    host=NAME[.DOMAIN]        Hostname for new DNS record
    type=TYPE or ID           Device/model type or ID
    ip=ADDRESS                IP address (numeric or dotted)

  Optional:
    notes=NOTES               Textual notes
    location=REF              Reference of location
    device=NAME|ID            The device this host is associated with

  Optional, add an interface too:
    mac=ADDRESS               Mac address (most formats are ok)
    name=NAME                 Interface name (i.e. "FastEthernet0/1.100")
    description=TEXT          Brief description of the interface
    addptr=Y|N                Auto add a PTR record for new host/IP (default: Y)


EOM
);
    }
    // Sanitize addptr.. set it to Y if it is not set
    $options['addptr'] = sanitize_YN($options['addptr'], 'Y');
    // clean up what is passed in
    $options['ip'] = trim($options['ip']);
    $options['mac'] = trim($options['mac']);
    $options['name'] = trim($options['name']);
    $options['host'] = trim($options['host']);
    // Validate that there isn't already another interface with the same IP address
    list($status, $rows, $interface) = ona_get_interface_record(array('ip_addr' => $options['ip']));
    if ($rows) {
        printmsg("DEBUG => host_add() IP conflict: That IP address (" . ip_mangle($orig_ip, 'dotted') . ") is already in use!", 3);
        $self['error'] = "ERROR => host_add() IP conflict: That IP address (" . ip_mangle($orig_ip, 'dotted') . ") is already in use!";
        return array(4, $self['error'] . "\n" . "INFO => Conflicting interface record ID: {$interface['id']}\n");
    }
    // Find the Location ID to use
    if ($options['location']) {
        list($status, $rows, $loc) = ona_find_location($options['location']);
        if ($status or !$rows) {
            printmsg("DEBUG => The location specified, {$options['location']}, does not exist!", 3);
            $self['error'] = "ERROR => The location specified, {$options['location']}, does not exist!";
            return array(2, "{$self['error']}\n");
        }
        printmsg("DEBUG => Location selected: {$loc['reference']}, location name: {$loc['name']}", 3);
    } else {
        $loc['id'] = 0;
    }
    // Find the Device Type ID (i.e. Type) to use
    list($status, $rows, $device_type) = ona_find_device_type($options['type']);
    if ($status or $rows != 1 or !$device_type['id']) {
        printmsg("DEBUG => The device type specified, {$options['type']}, does not exist!", 3);
        return array(3, "ERROR => The device type specified, {$options['type']}, does not exist!\n");
    }
    printmsg("DEBUG => Device type selected: {$device_type['model_description']} Device ID: {$device_type['id']}", 3);
    // Sanitize "security_level" option
    $options['security_level'] = sanitize_security_level($options['security_level']);
    if ($options['security_level'] == -1) {
        printmsg("DEBUG => Sanitize security level failed either ({$options['security_level']}) is invalid or is higher than user's level!", 3);
        return array(3, $self['error'] . "\n");
    }
    // Determine the real hostname to be used --
    // i.e. add .something.com, or find the part of the name provided
    // that will be used as the "domain".  This means testing many
    // domain names against the DB to see what's valid.
    //
    // Find the domain name piece of $search.
    // 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['domain']) {
        // Find the domain name piece of $search
        list($status, $rows, $domain) = ona_find_domain($options['domain'], 0);
    } else {
        list($status, $rows, $domain) = ona_find_domain($options['host'], 0);
    }
    if (!isset($domain['id'])) {
        printmsg("ERROR => Unable to determine domain name portion of ({$options['host']})!", 3);
        $self['error'] = "ERROR => Unable to determine domain name portion of ({$options['host']})!";
        return array(3, $self['error'] . "\n");
    }
    printmsg("DEBUG => ona_find_domain({$options['host']}) returned: {$domain['fqdn']}", 3);
    // Now find what the host part of $search is
    $hostname = str_replace(".{$domain['fqdn']}", '', $options['host']);
    // Validate that the DNS name has only valid characters in it
    $hostname = sanitize_hostname($hostname);
    if (!$hostname) {
        printmsg("ERROR => Invalid host name ({$options['host']})!", 3);
        $self['error'] = "ERROR => Invalid host name ({$options['host']})!";
        return array(4, $self['error'] . "\n");
    }
    // Debugging
    printmsg("DEBUG => Using hostname: {$hostname} Domainname: {$domain['fqdn']}, Domain ID: {$domain['id']}", 3);
    // Validate that there isn't already any dns record named $host['name'] in the domain $host_domain_id.
    $h_status = $h_rows = 0;
    // does the domain $host_domain_id even exist?
    list($d_status, $d_rows, $d_record) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id']));
    if ($d_status or $d_rows) {
        printmsg("DEBUG => The name {$hostname}.{$domain['fqdn']} is already in use, the primary name for a host should be unique!", 3);
        $self['error'] = "ERROR => Another DNS record named {$hostname}.{$domain['fqdn']} is already in use, the primary name for a host should be unique!";
        return array(5, $self['error'] . "\n");
    }
    // Check permissions
    if (!auth('host_add')) {
        $self['error'] = "Permission denied!";
        printmsg($self['error'], 0);
        return array(10, $self['error'] . "\n");
    }
    // Get the next ID for the new host record
    $id = ona_get_next_id('hosts');
    if (!$id) {
        $self['error'] = "ERROR => The ona_get_next_id('hosts') call failed!";
        printmsg($self['error'], 0);
        return array(7, $self['error'] . "\n");
    }
    printmsg("DEBUG => ID for new host record: {$id}", 3);
    // Get the next ID for the new device record or use the one passed in the CLI
    if (!$options['device']) {
        $host['device_id'] = ona_get_next_id('devices');
        if (!$id) {
            $self['error'] = "ERROR => The ona_get_next_id('device') call failed!";
            printmsg($self['error'], 0);
            return array(7, $self['error'] . "\n");
        }
        printmsg("DEBUG => ID for new device record: {$id}", 3);
    } else {
        list($status, $rows, $devid) = ona_find_device($options['device']);
        if (!$rows) {
            printmsg("DEBUG => The device specified, {$options['device']}, does not exist!", 3);
            $self['error'] = "ERROR => The device specified, {$options['device']}, does not exist!";
            return array(7, $self['error'] . "\n");
        }
        $host['device_id'] = $devid['id'];
    }
    // There is an issue with escaping '=' and '&'.  We need to avoid adding escape characters
    $options['notes'] = str_replace('\\=', '=', $options['notes']);
    $options['notes'] = str_replace('\\&', '&', $options['notes']);
    // Add the device record
    // FIXME: (MP) quick add of device record. more detail should be looked at here to ensure it is done right
    // FIXME: MP this should use the run_module('device_add')!!! when it is ready
    list($status, $rows) = db_insert_record($onadb, 'devices', array('id' => $host['device_id'], 'device_type_id' => $device_type['id'], 'location_id' => $loc['id'], 'primary_host_id' => $id));
    if ($status or !$rows) {
        $self['error'] = "ERROR => host_add() SQL Query failed adding device: " . $self['error'];
        printmsg($self['error'], 0);
        return array(6, $self['error'] . "\n");
    }
    // Add the host record
    // FIXME: (PK) Needs to insert to multiple tables for e.g. name and domain_id.
    list($status, $rows) = db_insert_record($onadb, 'hosts', array('id' => $id, 'primary_dns_id' => '', 'device_id' => $host['device_id'], 'notes' => $options['notes']));
    if ($status or !$rows) {
        $self['error'] = "ERROR => host_add() SQL Query failed adding host: " . $self['error'];
        printmsg($self['error'], 0);
        return array(6, $self['error'] . "\n");
    }
    // Else start an output message
    $text = "INFO => Host ADDED: {$hostname}.{$domain['fqdn']}";
    printmsg($text, 0);
    $text .= "\n";
    // We must always have an IP now to add an interface, call that module now:
    // since we have no name yet, we need to use the ID of the new host as the host option for the following module calls
    $options['host'] = $id;
    // for annoying reasons we need to keep track of what was set first
    $options['addptrsave'] = $options['addptr'];
    // Interface adds can add PTR records, lets let the A record add that happens next add it instead.
    $options['addptr'] = '0';
    printmsg("DEBUG => host_add() ({$hostname}.{$domain['fqdn']}) calling interface_add() ({$options['ip']})", 3);
    list($status, $output) = run_module('interface_add', $options);
    if ($status) {
        return array($status, $output);
    }
    $text .= $output;
    // Find the interface_id for the interface we just added
    list($status, $rows, $int) = ona_find_interface($options['ip']);
    // make the dns record type A
    $options['type'] = 'A';
    // FIXME: MP I had to force the name value here.  name is comming in as the interface name.  this is nasty!
    $options['name'] = "{$hostname}.{$domain['fqdn']}";
    $options['domain'] = $domain['fqdn'];
    // And we will go ahead and auto add the ptr.  the user can remove it later if they dont want it.  FIXME: maybe create a checkbox on the host edit
    $options['addptr'] = $options['addptrsave'];
    // Add the DNS entry with the IP address etc
    printmsg("DEBUG => host_add() ({$hostname}.{$domain['fqdn']}) calling dns_record_add() ({$options['ip']})", 3);
    list($status, $output) = run_module('dns_record_add', $options);
    if ($status) {
        return array($status, $output);
    }
    $text .= $output;
    // find the dns record we just added so we can use its ID as the primary_dns_id for the host.
    list($status, $rows, $dnsrecord) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'interface_id' => $int['id'], 'type' => 'A'));
    // Set the primary_dns_id to the dns record that was just added
    list($status, $rows) = db_update_record($onadb, 'hosts', array('id' => $id), array('primary_dns_id' => $dnsrecord['id']));
    if ($status or !$rows) {
        $self['error'] = "ERROR => host_add() SQL Query failed to update primary_dns_id for host: " . $self['error'];
        printmsg($self['error'], 0);
        return array(8, $self['error'] . "\n");
    }
    return array(0, $text);
}
Example #8
0
function rpt_output_text($form)
{
    global $onadb, $style, $images;
    // Provide a usage message here
    $usagemsg = <<<EOL
Report: nmap_scan
  Processes the XML output of an nmap scan and compares it to data in the database.

  Required:
    subnet=ID|IP|STRING   Subnet ID, IP, or name of existing subnet with a scan
      OR
    file=PATH             Local XML file will be sent to server for processing
      OR
    all                   Process ALL XML files on the server
      OR
    update_response       Update the last response field for all UP IPs to time in scan

  Output Formats:
    html
    text
    csv

NOTE: When running update_response, any entry that was updated will have a ~ indication
      at the beginning of the line.
      DNS names with a * preceeding them indicate there are more than one name available
      for this entry and it could have a more common name associated with it.

EOL;
    // Provide a usage message
    if ($form['rpt_usage']) {
        return array(0, $usagemsg);
    }
    if (!$form['totalhosts'] and !$form['all']) {
        return array(1, "\nERROR => No hosts found, check that the XML file is not empty, or that your subnet exists in the database.\n{$usagemsg}");
    }
    if (!$form['all']) {
        $text .= "NMAP scan of {$form['totalhosts']} hosts done on {$form['runtime']}. {$form['scansource']}\n\n";
    } else {
        $text .= "Displaying records for ALL nmap scans in the system.  It also only shows issues, not entries that are OK.\n\n";
    }
    //$text .= sprintf("%-50s %-8s %-8s\n",'NMAP SCAN','DATABASE','Actions');
    if ($form['csv_output']) {
        $text .= sprintf("%s,%s,%s,%s,%s,%s,%s,%s\n", 'STAT', 'NET IP', 'NET NAME', 'NET MAC', 'DB IP', 'DB NAME', 'DB MAC', 'ACTION');
    } else {
        $text .= sprintf("%-6s %-15s %-25s %-12s %-15s %-25s %-12s %s\n", 'STAT', 'NET IP', 'NET NAME', 'NET MAC', 'DB IP', 'DB NAME', 'DB MAC', 'ACTION');
    }
    // netip    netname     netmac      dbip    dbname  dbmac
    $poolhostcount = 0;
    // find out the broadcast IP for this subnet
    // TODO: fix this for ipv6 stuff!
    $num_hosts = 0xffffffff - ip_mangle($form['netcidr'], 'numeric');
    $broadcastip = ip_mangle(ip_mangle($form['netip'], 'numeric') + $num_hosts, 'dotted');
    foreach ((array) $form['ip'] as $record) {
        // scans with only one row in them may show up wrong, skip them
        if (!$record['netstatus'] and !$record['netip']) {
            continue;
        }
        $action = '';
        $upresp = ' ';
        // Check devices that are down
        if ($record['netstatus'] == "down") {
            // Skip over hosts that are not in network or database
            if ($record['dbip'] == "NOT FOUND") {
                continue;
            }
            // If it is only in the database then they should validate the ip or remove from database
            if ($record['netip'] == $record['dbip'] or $record['netdnsname'] != $record['dbdnsname']) {
                $action = "Ping to verify then delete as desired";
            }
        }
        // check devices that are up
        if ($record['netstatus'] == "up") {
            // If this is the subnet address or broadcast then skip it.  Sometimes nmap shows them as up
            if ($record['netip'] == $form['netip']) {
                continue;
            }
            if ($record['netip'] == $broadcastip) {
                continue;
            }
            // update the database last response field.
            if ($form['update_response'] and $record['dbip'] != "NOT FOUND") {
                //if (isset($options['dcm_output'])) { $text .=  "dcm.pl -r interface_modify interface={$record['ip']} set_last_response='{$runtime}'\n"; }
                list($updatestatus, $output) = run_module('interface_modify', array('interface' => $record['dbip'], 'set_last_response' => $form['runtime']));
                if ($updatestatus) {
                    $self['error'] = "ERROR => Failed to update response time for '{$record['dbip']}': " . $output;
                    printmsg($self['error'], 1);
                }
                $upresp = '~';
            }
            // Break out the host and domain parts of the name if we can
            if ($record['netdnsname']) {
                list($status, $rows, $domain) = ona_find_domain($record['netdnsname'], 0);
                // Now find what the host part of $search is
                $hostname = str_replace(".{$domain['fqdn']}", '', $record['netdnsname']);
            }
            // If we dont find it in the database
            if ($record['dbip'] == "NOT FOUND") {
                $action = "Add as host or Add as interface, check proper pool range";
            }
            // If it is in the database and network
            if ($record['netip'] == $record['dbip']) {
                $action = 'OK';
                // But if the names are not the same then action is partial
                if ($record['netdnsname'] != $record['dbdnsname']) {
                    $action = 'Update DNS';
                }
                if (strstr($record['dbdnsname'], '(')) {
                    $action = 'Update DNS PTR';
                }
            }
            // if the database name is empty, then provide a generic "name"
            if (!$record['dbdnsname'] and $record['dbip'] != 'NOT FOUND' and $record['netdnsname']) {
                $record['dbdnsname'] = 'NONE SET';
            }
            // if the names are different, offer an edit button for the DB
            if ($record['netdnsname'] and strtolower($record['netdnsname']) != $record['dbdnsname']) {
                // not a lot of testing here to make sure it will find the right name.
                list($status, $rows, $rptdnsrecord) = ona_find_dns_record($record['dbdnsname']);
            }
            // If the device is in a dhcp pool range, then count it and identify it.
            if ($record['inpool'] == 1) {
                $poolhostcount++;
                $record['dbip'] = 'DHCP Pooled';
                $action = 'DHCP Pooled device';
            }
        }
        // If we have more than 2 dns records, display info about them
        if ($record['dbdnsrows'] > 2) {
            $record['dbdnsname'] = '*' . $record['dbdnsname'];
        }
        /*
        TODO:
        * more testing of mac address stuff
        * display info about last response time.. add option to update last response form file.. flag if db has newer times than the scan
        */
        if ($form['csv_output']) {
            $txt = sprintf("%s,%s,%s,%s,%s,%s,%s,\"%s\"\n", $upresp . $record['netstatus'], $record['netip'], $record['netdnsname'], $record['netmacaddr'], $record['dbip'], $record['dbdnsname'] . ' ' . $record['dbdnsptrname'], $record['dbmacaddr'], $action);
        } else {
            $txt = sprintf("%-6s %-15s %-25s %-12s %-15s %-25s %-12s %s\n", $upresp . $record['netstatus'], $record['netip'], $record['netdnsname'], $record['netmacaddr'], $record['dbip'], $record['dbdnsname'] . ' ' . $record['dbdnsptrname'], $record['dbmacaddr'], $action);
        }
        // if we are in all mode, print only errors.. otherwise, print it all
        if ($form['all'] and $action == 'OK') {
            $txt = '';
        }
        // add the new line to the html output variable
        $text .= $txt;
    }
    if (!$form['all']) {
        $hostpoolinfo = "Hosts in DHCP pool range: {$poolhostcount}\n";
    }
    $text .= "\n{$hostpoolinfo}END OF REPORT";
    return array(0, $text);
}
Example #9
0
function ws_save($window_name, $form = '')
{
    global $include, $conf, $self, $onadb;
    // Check permissions (there is no interface_add, it's merged with host_add)
    if (!(auth('interface_modify') and auth('host_add'))) {
        $response = new xajaxResponse();
        $response->addScript("alert('Permission denied!');");
        return $response->getXML();
    }
    // If an array in a string was provided, build the array and store it in $form
    $form = parse_options_string($form);
    // Instantiate the xajaxResponse object
    $response = new xajaxResponse();
    $js = '';
    // Validate input
    if ($form['set_ip'] == '') {
        $response->addScript("alert('Please complete the IP address field to continue!');");
        return $response->getXML();
    }
    // set_create_a and set_create_ptr should both be set!
    if (!$form['set_addptr']) {
        $form['set_addptr'] = 'N';
    }
    // Decide if we're editing or adding
    $module = 'interface_modify';
    // If we're adding, re-map some the array names to match what the "add" module wants
    if (!$form['interface_id']) {
        $module = 'interface_add';
        $form['ip'] = $form['set_ip'];
        unset($form['set_ip']);
        $form['mac'] = $form['set_mac'];
        unset($form['set_mac']);
        $form['name'] = $form['set_name'];
        unset($form['set_name']);
        $form['description'] = $form['set_description'];
        unset($form['set_description']);
        $form['addptr'] = $form['set_addptr'];
        unset($form['set_addptr']);
        $form['view'] = $form['set_view'];
        unset($form['set_view']);
    } else {
        $form['interface'] = $form['interface_id'];
        unset($form['interface_id']);
    }
    // Do a pre check of the ptr domain so we can prompt the user properly
    if ($module == 'interface_add') {
        $ipflip = ip_mangle($form['ip'], 'flip');
        $octets = explode(".", $ipflip);
        //GD: ipv6 IPs must be reversed in .ip6.arpa
        if (count($octets) > 4) {
            $arpa = '.ip6.arpa';
            $octcount = 31;
        } else {
            $arpa = '.in-addr.arpa';
            $octcount = 3;
        }
        list($status, $rows, $ptrdomain) = ona_find_domain($ipflip . $arpa);
        if (!$ptrdomain['id']) {
            printmsg("ERROR => You must first create at least the following DNS domain: {$octets[$octcount]}{$arpa}", 3);
            $self['error'] = "ERROR => You must first create at least the following DNS domain: {$octets[$octcount]}{$arpa}.  You could also create domains for class B or class C level reverse zones.  Click OK to open add domain dialog";
            $response->addScript("alert('{$self['error']}');xajax_window_submit('edit_domain', 'newptrdomainname=>{$octets[$octcount]}{$arpa}', 'editor');");
            return $response->getXML();
        }
    }
    // Run the module
    list($status, $output) = run_module($module, $form);
    // If the module returned an error code display a popup warning
    if ($status) {
        $js .= "alert('Save failed.\\n" . preg_replace('/[\\s\']+/', ' ', $self['error']) . "');";
    } else {
        // If the module returned an error code display a popup warning
        if ($status and $module == 'modify' and $form['set_ip']) {
            $js .= "alert('Interface update failed.\\n" . preg_replace('/[\\s\']+/', ' ', $self['error']) . "');";
        } else {
            // Update the status to tell them what they just did if they just *added* a subnet and the "keep adding" box is checked.
            // Otherwise just close the edit window.
            if ($form['keepadding'] and $module == 'interface_add') {
                $js .= "el('statusinfo_{$window_name}').innerHTML = 'Previously added: {$form['ip']}';";
            } else {
                $js .= "removeElement('{$window_name}');";
            }
            // If there is "refresh" javascript, send it to the browser to execute
            if ($form['js']) {
                $js .= $form['js'];
            }
        }
    }
    // Insert the new table into the window
    $response->addScript($js);
    return $response->getXML();
}
Example #10
0
function ws_editor($window_name, $form = '')
{
    global $conf, $self, $onadb;
    global $font_family, $color, $style, $images;
    $window = array();
    // Check permissions
    if (!auth('advanced')) {
        $response = new xajaxResponse();
        $response->addScript("alert('Permission denied!');");
        return $response->getXML();
    }
    // If an array in a string was provided, build the array and store it in $form
    $form = parse_options_string($form);
    if ($form['server']) {
        list($status, $rows, $host) = ona_find_host($form['server']);
    }
    if ($form['host_id']) {
        list($status, $rows, $host) = ona_find_host($form['host_id']);
    }
    if ($form['domain']) {
        list($status, $rows, $domain) = ona_find_domain($form['domain']);
    }
    // Escape data for display in html
    foreach (array_keys((array) $host) as $key) {
        $host[$key] = htmlentities($host[$key], ENT_QUOTES, $conf['php_charset']);
    }
    // Set the window title:
    $window['title'] = "Assign domain to server";
    // Javascript to run after the window is built
    $window['js'] = <<<EOL
        /* Put a minimize icon in the title bar */
        el('{$window_name}_title_r').innerHTML =
            '&nbsp;<a onClick="toggle_window(\\'{$window_name}\\');" title="Minimize window" style="cursor: pointer;"><img src="{$images}/icon_minimize.gif" border="0" /></a>' +
            el('{$window_name}_title_r').innerHTML;

        /* Put a help icon in the title bar */
        el('{$window_name}_title_r').innerHTML =
            '&nbsp;<a href="{$_ENV['help_url']}{$window_name}" target="null" title="Help" style="cursor: pointer;"><img src="{$images}/silk/help.png" border="0" /></a>' +
            el('{$window_name}_title_r').innerHTML;

        suggest_setup('domain_server_name',  'suggest_domain_server_name');
        suggest_setup('domain_server_edit',  'suggest_domain_server_edit');

EOL;
    // Define the window's inner html
    $window['html'] = <<<EOL

    <!-- DNS server Edit Form -->
    <form id="{$window_name}_form" onSubmit="return false;">
    <input type="hidden" name="js" value="{$form['js']}">
    <table cellspacing="0" border="0" cellpadding="0" style="background-color: {$color['window_content_bg']}; padding-left: 20px; padding-right: 20px; padding-top: 5px; padding-bottom: 5px;">

        <tr>
            <td align="left" nowrap="true"><b><u>Assign Domain</u></b>&nbsp;</td>
            <td class="padding" align="left" width="100%">&nbsp;</td>
        </tr>

        <tr>
            <td class="input_required" align="right" nowrap="true">
                Server
            </td>
            <td class="padding" align="left" width="100%">
                <input
                    id="domain_server_name"
                    name="server"
                    alt="Server name"
                    value="{$host['fqdn']}"
                    class="edit"
                    type="text"
                    size="34" maxlength="255"
                >
               <div id="suggest_domain_server_name" class="suggest"></div>
            </td>
        </tr>


        <tr>
            <td class="input_required" align="right" nowrap="true">
                Domain
            </td>
            <td class="padding" align="left" width="100%">
                <input
                    id="domain_server_edit"
                    name="domain"
                    alt="Domain name"
                    value="{$domain['fqdn']}"
                    class="edit"
                    type="text"
                    size="34" maxlength="255"
                >
               <div id="suggest_domain_server_edit" class="suggest"></div>
            </td>
        </tr>

        <tr>
            <td class="input_required" align="right" nowrap="true">
                Role
            </td>
            <td class="padding" align="left" width="100%" nowrap="true">
                <select class="edit" name="role" alt="Role">
                    <option value="forward">Forward</option>
                    <option value="master" selected>Master</option>
                    <option value="slave">Slave</option>
                </select>
            </td>
        </tr>

        <tr>
            <td align="right" valign="top" nowrap="true">
                &nbsp;
            </td>
            <td class="padding" align="right" width="100%">
                <input type="hidden" name="overwrite" value="{$overwrite}">
                <input class="edit" type="button" name="cancel" value="Cancel" onClick="removeElement('{$window_name}');">
                <input class="edit" type="button"
                    name="submit"
                    value="Save"
                    accesskey=" "
                    onClick="xajax_window_submit('{$window_name}', xajax.getFormValues('{$window_name}_form'), 'save');"
                >
            </td>
        </tr>

    </table>
    </form>
EOL;
    return window_open($window_name, $window);
}
Example #11
0
function build_bind_domain($options = "")
{
    // The important globals
    global $conf, $self, $onadb;
    // Version - UPDATE on every edit!
    $version = '1.50';
    printmsg("DEBUG => build_bind_domain({$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']) {
        // NOTE: Help message lines should not exceed 80 characters for proper display on a console
        $self['error'] = 'ERROR => Insufficient parameters';
        return array(1, <<<EOF

build_bind_domain-v{$version}
Builds a zone file for a dns server from the database

  Synopsis: build_bind_domain [KEY=VALUE] ...

  Required:
    domain=DOMAIN or ID      build zone file for specified domain



EOF
);
    }
    // Get the domain information
    list($status, $rows, $domain) = ona_find_domain($options['domain']);
    printmsg("DEBUG => build_bind_domain() Domain record: {$domain['domain']}", 3);
    if (!$domain['id']) {
        printmsg("DEBUG => Unknown domain record: {$options['domain']}", 3);
        $self['error'] = "ERROR => Unknown domain record: {$options['domain']}";
        return array(2, $self['error'] . "\n");
    }
    // if for some reason the domains default_ttl is not set, use the one from the $conf['dns']['default_ttl']
    if ($domain['default_ttl'] == 0) {
        $domain['default_ttl'] = $conf['dns']['default_ttl'];
    }
    if ($domain['primary_master'] == '') {
        $domain['primary_master'] = 'localhost';
    }
    // loop through records and display them
    $q = "\n    SELECT  *\n    FROM    dns\n    WHERE   domain_id = {$domain['id']}\n    ORDER BY type";
    // exectue the query
    $rs = $onadb->Execute($q);
    if ($rs === false or !$rs->RecordCount()) {
        $self['error'] = 'ERROR => build_zone(): SQL query failed: ' . $onadb->ErrorMsg();
        printmsg($self['error'], 0);
        $exit += 1;
    }
    $rows = $rs->RecordCount();
    // check if this is a ptr domain that has delegation
    if (strpos(str_replace('in-addr.arpa', '', $domain['fqdn']), '-')) {
        $ptrdelegation = true;
    }
    // Start building the named.conf - save it in $text
    $text = "; DNS zone file for {$domain['fqdn']} built on " . date($conf['date_format']) . "\n";
    // print the opening host comment with row count
    $text .= "; TOTAL RECORDS (count={$rows})\n\n";
    // FIXME: MP do more to ensure that dots are at the end as appropriate
    $text .= "\$ORIGIN {$domain['fqdn']}.\n";
    $text .= "\$TTL {$domain['default_ttl']}\n";
    $text .= ";Serial number is current unix timestamp (seconds since UTC)\n\n";
    // NOTE: There are various ways that one could generate the serial.  The bind book suggests YYYYMMDDXX where XX is 1/100th of the day or some counter in the day.
    // I feel this is too limiting.  I prefer the Unix timestamp (seconds since UTC) method.  TinyDNS uses this method as well and it allows for much more granularity.
    // Referr to the following for some discussion on the topic: http://www.lifewithdjbdns.com/#Migration
    // NOTE: for now I am generating the serial each time the zone is built.  I'm ignoring, and may remove, the one stored in the database.
    $serial_number = time();
    // Build the SOA record
    // FIXME: MP do a bit more to ensure that dots are where they should be
    $text .= "@      IN      SOA   {$domain['primary_master']}. {$domain['admin_email']} ({$serial_number} {$domain['refresh']} {$domain['retry']} {$domain['expiry']} {$domain['minimum']})\n\n";
    // Loop through the record set
    while ($dnsrecord = $rs->FetchRow()) {
        // Dont build records that begin in the future
        if (strtotime($dnsrecord['ebegin']) > time()) {
            continue;
        }
        if (strtotime($dnsrecord['ebegin']) < 0) {
            continue;
        }
        // If there are notes, put the comment character in front of it
        if ($dnsrecord['notes']) {
            $dnsrecord['notes'] = '; ' . str_replace("\n", "; ", $dnsrecord['notes']);
        }
        // If the ttl is empty then make it truely empty
        if ($dnsrecord['ttl'] == 0) {
            $dnsrecord['ttl'] = '';
        }
        // Also, if the records ttl is the same as the domains ttl then dont display it, just to keep it "cleaner"
        if (!strcmp($dnsrecord['ttl'], $domain['default_ttl'])) {
            $dnsrecord['ttl'] = '';
        }
        // Dont print a dot unless hostname has a value
        if ($dnsrecord['name']) {
            $dnsrecord['name'] = $dnsrecord['name'] . '.';
        }
        if ($dnsrecord['type'] == 'A') {
            // Find the interface record
            list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id']));
            if ($status or !$rows) {
                printmsg("ERROR => Unable to find interface record!", 3);
                $self['error'] = "ERROR => Unable to find interface record!";
                return array(5, $self['error'] . "\n");
            }
            $fqdn = $dnsrecord['name'] . $domain['fqdn'];
            $text .= sprintf("%-50s %-8s IN  %-8s %-30s %s\n", $fqdn . '.', $dnsrecord['ttl'], $dnsrecord['type'], $interface['ip_addr_text'], $dnsrecord['notes']);
        }
        if ($dnsrecord['type'] == 'PTR') {
            // Find the interface record
            list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id']));
            if ($status or !$rows) {
                printmsg("ERROR => Unable to find interface record!", 3);
                $self['error'] = "ERROR => Unable to find interface record!";
                return array(5, $self['error'] . "\n");
            }
            // Get the name info that the cname points to
            list($status, $rows, $ptr) = ona_get_dns_record(array('id' => $dnsrecord['dns_id']), '');
            // If this is a delegation domain, find the subnet cidr
            if ($ptrdelegation) {
                list($status, $rows, $subnet) = ona_get_subnet_record(array('id' => $interface['subnet_id']));
                $ip_last = ip_mangle($interface['ip_addr'], 'flip');
                $ip_last_digit = substr($ip_last, 0, strpos($ip_last, '.'));
                $ip_remainder = substr($ip_last, strpos($ip_last, '.')) . '.in-addr.arpa.';
                $text .= sprintf("%-50s %-8s IN  %-8s %s.%-30s %s\n", $ip_last_digit . '-' . ip_mangle($subnet['ip_mask'], 'cidr') . $ip_remainder, $dnsrecord['ttl'], $dnsrecord['type'], $ptr['name'], $ptr['domain_fqdn'] . '.', $dnsrecord['notes']);
            } else {
                $text .= sprintf("%-50s %-8s IN  %-8s %s.%-30s %s\n", ip_mangle($interface['ip_addr'], 'flip') . '.in-addr.arpa.', $dnsrecord['ttl'], $dnsrecord['type'], $ptr['name'], $ptr['domain_fqdn'] . '.', $dnsrecord['notes']);
            }
        }
        if ($dnsrecord['type'] == 'CNAME') {
            // Find the interface record
            list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id']));
            if ($status or !$rows) {
                printmsg("ERROR => Unable to find interface record!", 3);
                $self['error'] = "ERROR => Unable to find interface record!";
                return array(5, $self['error'] . "\n");
            }
            // Get the name info that the cname points to
            list($status, $rows, $cname) = ona_get_dns_record(array('id' => $dnsrecord['dns_id']), '');
            $fqdn = $dnsrecord['name'] . $domain['fqdn'];
            $text .= sprintf("%-50s %-8s IN  %-8s %s.%-30s %s\n", $fqdn . '.', $dnsrecord['ttl'], $dnsrecord['type'], $cname['name'], $cname['domain_fqdn'] . '.', $dnsrecord['notes']);
        }
        if ($dnsrecord['type'] == 'NS') {
            // Find the interface record
            list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id']));
            if ($status or !$rows) {
                printmsg("ERROR => Unable to find interface record!", 3);
                $self['error'] = "ERROR => Unable to find interface record!";
                return array(5, $self['error'] . "\n");
            }
            // Get the name info that the cname points to
            list($status, $rows, $ns) = ona_get_dns_record(array('id' => $dnsrecord['dns_id']), '');
            $text .= sprintf("%-50s %-8s IN  %-8s %s.%-30s %s\n", $domain['fqdn'] . '.', $dnsrecord['ttl'], $dnsrecord['type'], $ns['name'], $ns['domain_fqdn'] . '.', $dnsrecord['notes']);
        }
        if ($dnsrecord['type'] == 'MX') {
            // Find the interface record
            list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id']));
            if ($status or !$rows) {
                printmsg("ERROR => Unable to find interface record!", 3);
                $self['error'] = "ERROR => Unable to find interface record!";
                return array(5, $self['error'] . "\n");
            }
            // Get the name info that the cname points to
            list($status, $rows, $mx) = ona_get_dns_record(array('id' => $dnsrecord['dns_id']), '');
            if ($dnsrecord['name']) {
                $name = $dnsrecord['name'] . $domain['fqdn'];
            } else {
                $name = $domain['name'];
            }
            $text .= sprintf("%-50s %-8s IN  %s %-5s %s.%-30s %s\n", $name . '.', $dnsrecord['ttl'], $dnsrecord['type'], $dnsrecord['mx_preference'], $mx['name'], $mx['domain_fqdn'] . '.', $dnsrecord['notes']);
        }
        if ($dnsrecord['type'] == 'SRV') {
            // Find the interface record
            list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id']));
            if ($status or !$rows) {
                printmsg("ERROR => Unable to find interface record!", 3);
                $self['error'] = "ERROR => Unable to find interface record!";
                return array(5, $self['error'] . "\n");
            }
            // Get the name info that the cname points to
            list($status, $rows, $srv) = ona_get_dns_record(array('id' => $dnsrecord['dns_id']), '');
            if ($dnsrecord['name']) {
                $name = $dnsrecord['name'] . $domain['fqdn'];
            } else {
                $name = $domain['name'];
            }
            $text .= sprintf("%-50s %-8s IN  %s %s %s %-8s %-30s %s\n", $name . '.', $dnsrecord['ttl'], $dnsrecord['type'], $dnsrecord['srv_pri'], $dnsrecord['srv_weight'], $dnsrecord['srv_port'], $srv['fqdn'] . '.', $dnsrecord['notes']);
        }
        if ($dnsrecord['type'] == 'TXT') {
            $fqdn = $dnsrecord['name'] . $domain['fqdn'];
            $text .= sprintf("%-50s %-8s IN  %-8s %-30s %s\n", $fqdn . '.', $dnsrecord['ttl'], $dnsrecord['type'], '"' . $dnsrecord['txt'] . '"', $dnsrecord['notes']);
        }
    }
    ////////////// Footer stuff //////////////////
    // MP: FIXME: For now I"m not using this.. bind errors out if the file doesnt exist.  need a deterministic way to do this.
    // Allow for a local footer include.. I expect this to rarely be used
    //    $text .= "\n; Allow for a local footer include.. I expect this to rarely be used.\n";
    //    $text .= "\$INCLUDE named-{$domain['fqdn']}-footer\n";
    // Return the zone file
    return array(0, $text);
}
Example #12
0
File: 2-to-3.php Project: edt82/ona
    if (!$interface['ip_addr']) {
        echo "Possible orphan PTR record in dns table at ID: {$ptr['id']}.  You should delete this record manually.\n";
        continue;
    }
    $ipflip = ip_mangle($interface['ip_addr'], 'flip');
    $octets = explode(".", $ipflip);
    // Find a pointer domain for this record to associate with.
    list($status, $rows, $ptrdomain) = ona_find_domain($ipflip . ".in-addr.arpa", 0);
    // CRAPPY security cludge
    $_SESSION['ona']['auth']['user']['username'] = '******';
    $_SESSION['ona']['auth']['perms']['advanced'] = 'Y';
    $_SESSION['ona']['auth']['perms']['host_modify'] = 'Y';
    if (!$ptrdomain['id']) {
        echo "  {$interface['ip_addr_text']}: Unable to find a pointer domain for this IP! Creating the following DNS domain: {$octets[3]}.in-addr.arpa\n";
        list($status, $output) = run_module('domain_add', array('name' => $octets[3] . '.in-addr.arpa'));
        if ($status) {
            echo "ERROR => {$output}\n";
            exit($status);
        }
        list($status, $rows, $ptrdomain) = ona_find_domain($ipflip . ".in-addr.arpa", 0);
    }
    // Found a domain to put them in.
    echo "  Updating PTR for IP {$interface['ip_addr_text']} to domain {$ptrdomain['fqdn']}\n";
    // Change the actual DNS record
    list($status, $rows) = db_update_record($onadb, 'dns', array('id' => $ptr['id']), array('domain_id' => $ptrdomain['id']));
    if ($status or !$rows) {
        echo "ERROR => SQL Query failed updating dns record: " . $self['error'];
        exit(2);
    }
}
exit(0);
Example #13
0
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, transform it into an array
    $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');";
    // If it's not a new query, load the previous query from the session
    // into $form and save the current page and filter in the session.
    // Also find/set the "page" we're viewing
    $page = 1;
    if ($form['page'] and is_numeric($form['page'])) {
        $form = array_merge($form, (array) $_SESSION['ona'][$form['form_id']][$tab]['q']);
        $_SESSION['ona'][$form['form_id']][$tab]['page'] = $page = $form['page'];
        $_SESSION['ona'][$form['form_id']][$tab]['filter'] = $form['filter'];
    }
    printmsg("DEBUG => Displaying hosts list page: {$page}", 1);
    // Calculate the SQL query offset (based on the page being displayed)
    $offset = $conf['search_results_per_page'] * ($page - 1);
    if ($offset == 0) {
        $offset = -1;
    }
    // Search results go in here
    $results = array();
    $count = 0;
    //
    // *** ADVANCED HOST SEARCH ***
    //       FIND RESULT SET
    //
    // Start building the "where" clause for the sql query to find the hosts to display
    $where = "";
    $and = "";
    $orderby = "";
    $from = 'hosts h';
    // enable or disable wildcards
    $wildcard = '%';
    if ($form['nowildcard']) {
        $wildcard = '';
    }
    // DISPLAY ALL
    // MP: I dont think this is used.. remove it if you can
    if ($form['all_flag']) {
        $where .= $and . "h.id > 0";
        $and = " AND ";
    }
    // HOST ID
    if ($form['host_id']) {
        $where .= $and . "h.id = " . $onadb->qstr($form['host_id']);
        $and = " AND ";
    }
    // DEVICE ID
    if ($form['device_id']) {
        $where .= $and . "h.device_id = " . $onadb->qstr($form['device_id']);
        $and = " AND ";
    }
    // HOSTNAME
    if ($form['hostname']) {
        // Find the domain name piece of the hostname assuming it was passed in as an fqdn.
        // FIXME: MP this was taken from the ona_find_domain function. make that function have the option
        // to NOT return a default domain.
        // lets test out if it has a / in it to strip the view name portion
        $view['id'] = 0;
        if (strstr($form['hostname'], '/')) {
            list($dnsview, $form['hostname']) = explode('/', $form['hostname']);
            list($status, $viewrows, $view) = db_get_record($onadb, 'dns_views', array('name' => strtoupper($dnsview)));
            if (!$viewrows) {
                $view['id'] = 0;
            }
        }
        // Split it up on '.' and put it in an array backwards
        $parts = array_reverse(explode('.', $form['hostname']));
        // Find the domain name that best matches
        $name = '';
        $domain = array();
        foreach ($parts as $part) {
            if (!$rows) {
                if (!$name) {
                    $name = $part;
                } else {
                    $name = "{$part}.{$name}";
                }
                list($status, $rows, $record) = ona_get_domain_record(array('name' => $name));
                if ($rows) {
                    $domain = $record;
                }
            } else {
                list($status, $rows, $record) = ona_get_domain_record(array('name' => $part, 'parent_id' => $domain['id']));
                if ($rows) {
                    $domain = $record;
                }
            }
        }
        $withdomain = '';
        $hostname = $form['hostname'];
        // If you found a domain in the query, add it to the search, and strip the domain from the host portion.
        if (array_key_exists('id', $domain) and !$form['domain']) {
            $withdomain = "AND b.domain_id = {$domain['id']}";
            // Now find what the host part of $search is
            $hostname = str_replace(".{$domain['fqdn']}", '', $form['hostname']);
        }
        // If we have a hostname and a domain name then use them both
        if ($form['domain']) {
            list($status, $rows, $record) = ona_find_domain($form['domain']);
            if ($record['id']) {
                $withdomain = "AND b.domain_id = {$record['id']}";
            }
            // Now find what the host part of $search is
            $hostname = trim($form['hostname']);
        }
        // MP: Doing the many select IN statements was too slow.. I did this kludge:
        //  1. get a list of all the interfaces
        //  2. loop through the array and build a list of comma delimited host_ids to use in the final select
        list($status, $rows, $tmp) = db_get_records($onadb, 'interfaces a, dns b', "a.id = b.interface_id and b.name LIKE '{$wildcard}{$hostname}{$wildcard}' {$withdomain}");
        $commait = '';
        $hostids = '';
        foreach ($tmp as $item) {
            $hostids .= $commait . $item['host_id'];
            $commait = ',';
        }
        // Just look for the host itself
        list($status, $rows, $r) = ona_find_host($form['hostname']);
        if ($rows) {
            $hostids .= ',' . $r['id'];
        }
        // MP: this is the old, slow query for reference.
        //
        // TODO: MP this seems to be kinda slow (gee I wonder why).. look into speeding things up somehow.
        //       This also does not search for CNAME records etc.  only things with interface_id.. how to fix that issue.......?
        //        $where .= $and . "id IN (select host_id from interfaces where id in (SELECT interface_id " .
        //                                "  FROM dns " .
        //                                "  WHERE name LIKE '%{$hostname}%' {$withdomain} ))";
        // Trim off extra commas
        $hostids = trim($hostids, ",");
        // If we got a list of hostids from interfaces then use them
        if ($hostids) {
            $idqry = "h.id IN ({$hostids})";
        } else {
            $idqry = "";
        }
        $where .= $and . $idqry;
        $and = " AND ";
    }
    // DOMAIN
    if ($form['domain'] and !$form['hostname']) {
        // FIXME: does this clause work correctly?
        printmsg("FIXME: => Does \$form['domain'] work correctly in list_hosts.inc.php?", 2);
        // Find the domain name piece of the hostname.
        // FIXME: MP this was taken from the ona_find_domain function. make that function have the option
        // to NOT return a default domain.
        // Split it up on '.' and put it in an array backwards
        $parts = array_reverse(explode('.', $form['domain']));
        // Find the domain name that best matches
        $name = '';
        $domain = array();
        foreach ($parts as $part) {
            if (!$rows) {
                if (!$name) {
                    $name = $part;
                } else {
                    $name = "{$part}.{$name}";
                }
                list($status, $rows, $record) = ona_get_domain_record(array('name' => $name));
                if ($rows) {
                    $domain = $record;
                }
            } else {
                list($status, $rows, $record) = ona_get_domain_record(array('name' => $part, 'parent_id' => $domain['id']));
                if ($rows) {
                    $domain = $record;
                }
            }
        }
        if (array_key_exists('id', $domain)) {
            // Crappy way of writing the query but it makes it fast.
            $from = "(\nSELECT distinct a.*\nfrom hosts as a, interfaces as i, dns as d\nwhere a.id = i.host_id\nand i.id = d.interface_id\nand d.domain_id = " . $onadb->qstr($domain['id']) . "\n) h";
            $and = " AND ";
        }
    }
    // DOMAIN ID
    if ($form['domain_id'] and !$form['hostname']) {
        $where .= $and . "h.primary_dns_id IN ( SELECT id " . "  FROM dns " . "  WHERE domain_id = " . $onadb->qstr($form['domain_id']) . " )  ";
        $and = " AND ";
    }
    // MAC
    if ($form['mac']) {
        // Clean up the mac address
        $form['mac'] = strtoupper($form['mac']);
        $form['mac'] = preg_replace('/[^%0-9A-F]/', '', $form['mac']);
        // We do a sub-select to find interface id's that match
        $where .= $and . "h.id IN ( SELECT host_id " . "        FROM interfaces " . "        WHERE mac_addr LIKE " . $onadb->qstr($wildcard . $form['mac'] . $wildcard) . " ) ";
        $and = " AND ";
    }
    // IP ADDRESS
    $ip = $ip_end = '';
    if ($form['ip']) {
        // Build $ip and $ip_end from $form['ip'] and $form['ip_thru']
        $ip = ip_complete($form['ip'], '0');
        if ($form['ip_thru']) {
            $ip_end = ip_complete($form['ip_thru'], '255');
        } else {
            $ip_end = ip_complete($form['ip'], '255');
        }
        // Find out if $ip and $ip_end are valid
        $ip = ip_mangle($ip, 'numeric');
        $ip_end = ip_mangle($ip_end, 'numeric');
        if ($ip != -1 and $ip_end != -1) {
            // We do a sub-select to find interface id's between the specified ranges
            $where .= $and . "h.id IN ( SELECT host_id " . "        FROM interfaces " . "        WHERE ip_addr >= " . $onadb->qstr($ip) . " AND ip_addr <= " . $onadb->qstr($ip_end) . " )";
            $and = " AND ";
        }
    }
    // NOTES
    if ($form['notes']) {
        $where .= $and . "h.notes LIKE " . $onadb->qstr($wildcard . $form['notes'] . $wildcard);
        $and = " AND ";
    }
    // DEVICE MODEL
    if ($form['model_id']) {
        $where .= $and . "h.device_id in (select id from devices where device_type_id in (select id from device_types where model_id = {$form['model_id']}))";
        $and = " AND ";
    }
    if ($form['model']) {
        $where .= $and . "h.device_id in (select id from devices where device_type_id in (select id from device_types where model_id in (select id from models where name like '{$form['model']}')))";
        $and = " AND ";
    }
    // DEVICE TYPE
    if ($form['role']) {
        // Find model_id's that have a device_type_id of $form['role']
        list($status, $rows, $records) = db_get_records($onadb, 'roles', array('name' => $form['role']));
        // If there were results, add each one to the $where clause
        if ($rows > 0) {
            $where .= $and . " ( ";
            $and = " AND ";
            $or = "";
            foreach ($records as $record) {
                // Yes this is one freakin nasty query but it works.
                $where .= $or . "h.device_id in (select id from devices where device_type_id in (select id from device_types where role_id = " . $onadb->qstr($record['id']) . "))";
                $or = " OR ";
            }
            $where .= " ) ";
        }
    }
    // DEVICE MANUFACTURER
    if ($form['manufacturer']) {
        // Find model_id's that have a device_type_id of $form['manufacturer']
        if (is_numeric($form['manufacturer'])) {
            list($status, $rows, $records) = db_get_records($onadb, 'models', array('manufacturer_id' => $form['manufacturer']));
        } else {
            list($status, $rows, $manu) = db_get_record($onadb, 'manufacturers', array('name' => $form['manufacturer']));
            list($status, $rows, $records) = db_get_records($onadb, 'models', array('manufacturer_id' => $manu['id']));
        }
        // If there were results, add each one to the $where clause
        if ($rows > 0) {
            $where .= $and . " ( ";
            $and = " AND ";
            $or = "";
            foreach ($records as $record) {
                // Yes this is one freakin nasty query but it works.
                $where .= $or . "h.device_id in (select id from devices where device_type_id in (select id from device_types where model_id = " . $onadb->qstr($record['id']) . "))";
                $or = " OR ";
            }
            $where .= " ) ";
        }
    }
    // tag
    if ($form['tag_host']) {
        $where .= $and . "h.id in (select reference from tags where type like 'host' and name like " . $onadb->qstr($form['tag_host']) . ")";
        $and = " AND ";
    }
    // custom attribute type
    if ($form['custom_attribute_type']) {
        $where .= $and . "h.id in (select table_id_ref from custom_attributes where table_name_ref like 'hosts' and custom_attribute_type_id = (SELECT id FROM custom_attribute_types WHERE name = " . $onadb->qstr($form['custom_attribute_type']) . "))";
        $and = " AND ";
        $cavaluetype = "and custom_attribute_type_id = (SELECT id FROM custom_attribute_types WHERE name = " . $onadb->qstr($form['custom_attribute_type']) . ")";
    }
    // custom attribute value
    if ($form['ca_value']) {
        $where .= $and . "h.id in (select table_id_ref from custom_attributes where table_name_ref like 'hosts' {$cavaluetype} and value like " . $onadb->qstr($wildcard . $form['ca_value'] . $wildcard) . ")";
        $and = " AND ";
    }
    // LOCATION No.
    if ($form['location']) {
        list($status, $rows, $loc) = ona_find_location($form['location']);
        $where .= $and . "h.device_id in (select id from devices where location_id = " . $onadb->qstr($loc['id']) . ")";
        $and = " AND ";
    }
    // subnet ID
    if (is_numeric($form['subnet_id'])) {
        // We do a sub-select to find interface id's that match
        $from = "(\nSELECT distinct a.*\nfrom hosts as a, interfaces as b\nwhere a.id = b.host_id\nand b.subnet_id = " . $onadb->qstr($form['subnet_id']) . "\norder by b.ip_addr) h";
        $and = " AND ";
    }
    // display a nice message when we dont find all the records
    if ($where == '' and $form['content_id'] == 'search_results_list') {
        $js .= "el('search_results_msg').innerHTML = 'Unable to find hosts matching your query, showing all records';";
    }
    // Wild card .. if $while is still empty, add a 'ID > 0' to it so you see everything.
    if ($where == '') {
        $where = 'h.id > 0';
    }
    // Do the SQL Query
    $filter = '';
    if ($form['filter']) {
        // Host names should always be lower case
        $form['filter'] = strtolower($form['filter']);
        // FIXME (MP) for now this uses primary_dns_id, this will NOT find multiple A records or other record types. Find a better way some day
        $filter = " AND h.primary_dns_id IN  (SELECT id " . " FROM dns " . " WHERE name LIKE " . $onadb->qstr('%' . $form['filter'] . '%') . " )  ";
    }
    list($status, $rows, $results) = db_get_records($onadb, $from, $where . $filter, $orderby, $conf['search_results_per_page'], $offset);
    // If we got less than serach_results_per_page, add the current offset to it
    // so that if we're on the last page $rows still has the right number in it.
    if ($rows > 0 and $rows < $conf['search_results_per_page']) {
        $rows += $conf['search_results_per_page'] * ($page - 1);
    } else {
        if ($rows >= $conf['search_results_per_page']) {
            list($status, $rows, $records) = db_get_records($onadb, $from, $where . $filter, "", 0);
        }
    }
    $count = $rows;
    //
    // *** BUILD HTML LIST ***
    //
    $html .= <<<EOL
        <!-- Host Results -->
        <table id="{$form['form_id']}_host_list" class="list-box" cellspacing="0" border="0" cellpadding="0">

            <!-- Table Header -->
            <tr>
                <td class="list-header" align="center" style="{$style['borderR']};">Name</td>
                <td class="list-header" align="center" style="{$style['borderR']};">Subnet</td>
                <td class="list-header" align="center" style="{$style['borderR']};">Interface</td>
                <td class="list-header" align="center" style="{$style['borderR']};">Device Type</td>
                <td class="list-header" align="center" style="{$style['borderR']};">Location</td>
                <td class="list-header" align="center" style="{$style['borderR']};">Notes</td>
                <td class="list-header" align="center">&nbsp;</td>
            </tr>
EOL;
    // Loop and display each record
    foreach ($results as $record) {
        // Get additional info about eash host record
        // If a subnet_id was passed use it as part of the search.  Used to display the IP of the subnet you searched
        if (is_numeric($form['subnet_id'])) {
            list($status, $interfaces, $interface) = ona_get_interface_record(array('host_id' => $record['id'], 'subnet_id' => $form['subnet_id']), '');
            // Count how many rows and assign it back to the interfaces variable
            list($status, $rows, $records) = db_get_records($onadb, 'interfaces', 'host_id = ' . $onadb->qstr($record['id']), "ip_addr", 0);
            $interfaces = $rows;
        } else {
            if (is_numeric($ip)) {
                list($status, $interfaces, $interface) = db_get_record($onadb, 'interfaces', 'host_id = ' . $onadb->qstr($record['id']) . ' AND ip_addr >= ' . $onadb->qstr($ip) . ' AND ip_addr <= ' . $onadb->qstr($ip_end), "ip_addr", 0);
                // Count how many rows and assign it back to the interfaces variable
                list($status, $rows, $records) = db_get_records($onadb, 'interfaces', 'host_id = ' . $onadb->qstr($record['id']), "ip_addr", 0);
                $interfaces = $rows;
            } else {
                // Interface (and find out how many there are)
                list($status, $interfaces, $interface) = ona_get_interface_record(array('host_id' => $record['id']), '');
            }
        }
        // bz: why did someone add this??  You especially want to show hosts with no interfaces so you can fix them!
        // if (!$interfaces) {$count -1; continue;}
        // get interface cluster info
        $clusterhtml = '';
        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_{$record['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_{$record['id']},interface_id=>{$interface['id']}\\');'\n                    );\"";
            $clusterhtml .= <<<EOL
                <img src="{$images}/silk/sitemap.png" {$clusterscript} />
EOL;
        }
        $record['ip_addr'] = ip_mangle($interface['ip_addr'], 'dotted');
        $interface_style = '';
        if ($interfaces > 1) {
            $interface_style = 'font-weight: bold;';
        }
        // DNS A record
        list($status, $rows, $dns) = ona_get_dns_record(array('id' => $record['primary_dns_id']));
        $record['name'] = $dns['name'];
        // Domain Name
        list($status, $rows, $domain) = ona_get_domain_record(array('id' => $dns['domain_id']));
        $record['domain'] = $domain['fqdn'];
        // Subnet description
        list($status, $rows, $subnet) = ona_get_subnet_record(array('id' => $interface['subnet_id']));
        $record['subnet'] = $subnet['name'];
        $record['ip_mask'] = ip_mangle($subnet['ip_mask'], 'dotted');
        $record['ip_mask_cidr'] = ip_mangle($subnet['ip_mask'], 'cidr');
        // Device Description
        list($status, $rows, $device) = ona_get_device_record(array('id' => $record['device_id']));
        list($status, $rows, $device_type) = ona_get_device_type_record(array('id' => $device['device_type_id']));
        list($status, $rows, $model) = ona_get_model_record(array('id' => $device_type['model_id']));
        list($status, $rows, $role) = ona_get_role_record(array('id' => $device_type['role_id']));
        list($status, $rows, $manufacturer) = ona_get_manufacturer_record(array('id' => $model['manufacturer_id']));
        $record['devicefull'] = "{$manufacturer['name']}, {$model['name']} ({$role['name']})";
        $record['device'] = str_replace('Unknown', '?', $record['devicefull']);
        $record['notes_short'] = truncate($record['notes'], 40);
        // Get location_number from the location_id
        list($status, $rows, $location) = ona_get_location_record(array('id' => $device['location_id']));
        // Escape data for display in html
        foreach (array_keys($record) as $key) {
            $record[$key] = htmlentities($record[$key], ENT_QUOTES, $conf['php_charset']);
        }
        $primary_object_js = "xajax_window_submit('work_space', 'xajax_window_submit(\\'display_host\\', \\'host_id=>{$record['id']}\\', \\'display\\')');";
        $html .= <<<EOL
            <tr onMouseOver="this.className='row-highlight';" onMouseOut="this.className='row-normal';">

                <td class="list-row">
                    <a title="View host. ID: {$record['id']}"
                       class="nav"
                       onClick="{$primary_object_js}"
                    >{$record['name']}</a
                    >.<a title="View domain. ID: {$domain['id']}"
                         class="domain"
                         onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_domain\\', \\'domain_id=>{$domain['id']}\\', \\'display\\')');"
                    >{$record['domain']}</a>
                </td>

                <td class="list-row">
                    <a title="View subnet. ID: {$subnet['id']}"
                         class="nav"
                         onClick="xajax_window_submit('work_space', 'xajax_window_submit(\\'display_subnet\\', \\'subnet_id=>{$subnet['id']}\\', \\'display\\')');"
                    >{$record['subnet']}</a>&nbsp;
                </td>

                <td class="list-row" align="left">
                    <span style="{$interface_style}"
EOL;
        if ($interfaces > 1) {
            $html .= <<<EOL
                          onMouseOver="wwTT(this, event,
                                            'id', 'tt_host_interface_list_{$record['id']}',
                                            'type', 'velcro',
                                            'styleClass', 'wwTT_niceTitle',
                                            'direction', 'south',
                                            'javascript', 'xajax_window_submit(\\'tooltips\\', \\'tooltip=>host_interface_list,id=>tt_host_interface_list_{$record['id']},host_id=>{$record['id']}\\');'
                                           );"
EOL;
        }
        $html .= <<<EOL
                    >{$record['ip_addr']}</span>&nbsp;
                    <span title="{$record['ip_mask']}">/{$record['ip_mask_cidr']}</span>
                    <span>{$clusterhtml}</span>
                </td>

                <td class="list-row" title="{$record['devicefull']}">{$record['device']}&nbsp;</td>

                <td class="list-row" align="right">
                    <span onMouseOver="wwTT(this, event,
                                            'id', 'tt_location_{$device['location_id']}',
                                            'type', 'velcro',
                                            'styleClass', 'wwTT_niceTitle',
                                            'direction', 'south',
                                            'javascript', 'xajax_window_submit(\\'tooltips\\', \\'tooltip=>location,id=>tt_location_{$device['location_id']},location_id=>{$device['location_id']}\\');'
                                           );"
                    >{$location['reference']}</span>&nbsp;
                </td>

                <td class="list-row">
                    <span title="{$record['notes']}">{$record['notes_short']}</span>&nbsp;
                </td>

                <!-- ACTION ICONS -->
                <td class="list-row" align="right">
                    <form id="{$form['form_id']}_list_host_{$record['id']}"
                        ><input type="hidden" name="host_id" value="{$record['id']}"
                        ><input type="hidden" name="js" value="{$refresh}"
                    ></form>&nbsp;
EOL;
        if (auth('host_modify')) {
            $html .= <<<EOL

                    <a title="Edit host"
                       class="act"
                       onClick="xajax_window_submit('edit_host', xajax.getFormValues('{$form['form_id']}_list_host_{$record['id']}'), 'editor');"
                    ><img src="{$images}/silk/page_edit.png" border="0"></a>&nbsp;
EOL;
        }
        if (auth('host_del')) {
            $html .= <<<EOL

                    <a title="Delete host"
                       class="act"
                       onClick="xajax_window_submit('edit_host', xajax.getFormValues('{$form['form_id']}_list_host_{$record['id']}'), 'delete');"
                    ><img src="{$images}/silk/delete.png" border="0"></a>
EOL;
        }
        $html .= <<<EOL
                    &nbsp;
                </td>

            </tr>
EOL;
    }
    if ($count == 0 and $form['subnet_id'] and !$form['filter']) {
        $html .= <<<EOL
     <tr><td colspan="99" align="center" style="color: red;">Please add the gateway host (router) to this subnet</td></tr>
EOL;
    }
    $html .= <<<EOL
    </table>
EOL;
    // Build page links if there are any
    $html .= get_page_links($page, $conf['search_results_per_page'], $count, $window_name, $form['form_id']);
    // If there was only 1 result, and we're about to display results in the "Search Results" window, display it.
    if ($count == 1 and $form['content_id'] == 'search_results_list' and $form['filter'] == '') {
        $js .= $primary_object_js;
    }
    // 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();
}
Example #14
0
function domain_add($options = "")
{
    global $conf, $self, $onadb;
    printmsg("DEBUG => domain_add({$options}) called", 3);
    // Version - UPDATE on every edit!
    $version = '1.07';
    // Parse incoming options string to an array
    $options = parse_options($options);
    // Return the usage summary if we need to
    if ($options['help'] or !($options['name'] or ($options['admin'] or $options['ptr'] or $options['primary_master']))) {
        // 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_add-v{$version}
Adds a DNS domain into the database

  Synopsis: domain_add [KEY=VALUE] ...

  Required:
    name=STRING                             full name of new domain
                                            (i.e. name.something.com)

  Optional:
    admin=STRING                            Default ({$conf['dns_admin_email']})
    primary_master=STRING                   Default ({$conf['dns_primary_master']})
    refresh=NUMBER                          Default ({$conf['dns_refresh']})
    retry=NUMBER                            Default ({$conf['dns_retry']})
    expiry=NUMBER                           Default ({$conf['dns_expiry']})
    minimum=NUMBER                          Default ({$conf['dns_minimum']})
    parent=DOMAIN_NAME                      Default ({$conf['dns_parent']})
    ttl=NUMBER                              Default ({$conf['dns_default_ttl']})


EOM
);
    }
    // Use default if something was not passed on command line
    if ($options['admin']) {
        $admin = $options['admin'];
    } else {
        $admin = $conf['dns_admin_email'];
    }
    if ($options['primary_master']) {
        $primary = $options['primary_master'];
    } else {
        $primary = $conf['dns_primary_master'];
    }
    if ($options['refresh']) {
        $refresh = $options['refresh'];
    } else {
        $refresh = $conf['dns_refresh'];
    }
    if ($options['retry']) {
        $retry = $options['retry'];
    } else {
        $retry = $conf['dns_retry'];
    }
    if ($options['expiry']) {
        $expiry = $options['expiry'];
    } else {
        $expiry = $conf['dns_expiry'];
    }
    if ($options['minimum']) {
        $minimum = $options['minimum'];
    } else {
        $minimum = $conf['dns_minimum'];
    }
    if ($options['ttl']) {
        $ttl = $options['ttl'];
    } else {
        $ttl = $conf['dns_default_ttl'];
    }
    $options['name'] = trim($options['name']);
    $options['parent'] = trim($options['parent']);
    $options['primary_master'] = trim($options['primary_master']);
    $options['admin'] = trim($options['admin']);
    // Setup array for searching existing domains
    $exist_domain = array('name' => $options['name']);
    // get parent domain info
    if ($options['parent']) {
        list($status, $rows, $parent_domain) = ona_find_domain($options['parent'], 0);
        if (!isset($parent_domain['id'])) {
            printmsg("DEBUG => The parent domain specified ({$options['parent']}) does not exist!", 3);
            $self['error'] = "ERROR => The parent domain specified, {$options['parent']}, does not exist!";
            return array(5, $self['error'] . "\n");
        }
        // Set up the parent part of the search if there was one
        $exist_domain['parent_id'] = $parent_domain['id'];
    } else {
        $parent_domain['id'] = 0;
    }
    // Validate that this domain doesnt already exist
    list($status, $rows, $record) = ona_get_domain_record($exist_domain);
    if ($record['id']) {
        printmsg("DEBUG => The domain specified ({$record['name']}) already exists!", 3);
        $self['error'] = "ERROR => The domain specified, {$options['name']}, already exists!";
        return array(11, $self['error'] . "\n");
    }
    if (is_string($options['name'])) {
        // FIXME: not sure if its needed but this was calling sanitize_domainname, which did not exist
        $domain_name = sanitize_hostname($options['name']);
        if (!is_string($domain_name)) {
            printmsg("DEBUG => The domain name ({$options['name']}) is invalid!", 3);
            $self['error'] = "ERROR => The domain name ({$options['name']}) is invalid!";
            return array(4, $self['error'] . "\n");
        }
    }
    // FIXME: MP for now this is removed.  it is a chicken/egg issue on setting this name
    //   Also it cant use find_host as the name is not always primary dns name.
    //     if ($primary) {
    //         // Determine the primary master is a valid host
    //         list($status, $rows, $ohost) = ona_find_host($primary);
    //
    //         if (!$ohost['id']) {
    //             printmsg("DEBUG => The primary master host specified ({$primary}) does not exist!", 3);
    //             $self['error'] = "ERROR => The primary master host specified ({$primary}) does not exist!";
    //             return(array(2, $self['error'] . "\n"));
    //         }
    //
    //     }
    // Check permissions
    if (!auth('advanced')) {
        $self['error'] = "Permission denied!";
        printmsg($self['error'], 0);
        return array(10, $self['error'] . "\n");
    }
    // Get the next ID
    $first_id = $id = ona_get_next_id('domains');
    if (!$id) {
        $self['error'] = "ERROR => The ona_get_next_id('domains') call failed!";
        printmsg($self['error'], 0);
        return array(6, $self['error'] . "\n");
    }
    printmsg("DEBUG => domain_add(): New domain ID: {$id} name: {$domain_name}.{$parent_domain['fqdn']}", 3);
    // come up with a serial_number
    // Calculate a serial based on time
    // concatinate year,month,day,percentage of day
    // FIXME: MP this needs more work to be more accurate.  maybe not use date.. pretty limiting at 10 characters as suggested here: http://www.zytrax.com/books/dns/ch8/soa.html
    // for now I'm going with non zero padded(zp) month,zp day, zp hour, zp minute, zp second.  The only issue I can see at this point with this is when it rolls to january..
    // will that be too much of an increment for it to properly zone xfer?  i.e.  1209230515 = 12/09 23:05:15 in time format
    // MP: FOR NOW SERIAL WONT EVER GET USED...  LEFT IT IN HERE FOR AWHILE THOUGH
    $serial_number = date('njHis');
    // Add the record
    list($status, $rows) = db_insert_record($onadb, 'domains', array('id' => $id, 'name' => $domain_name, 'primary_master' => $primary, 'admin_email' => $admin, 'refresh' => $refresh, 'retry' => $retry, 'expiry' => $expiry, 'minimum' => $minimum, 'default_ttl' => $ttl, 'parent_id' => $parent_domain['id'], 'serial' => $serial_number));
    if ($status or !$rows) {
        $self['error'] = "ERROR => domain_add() SQL Query failed: " . $self['error'];
        printmsg($self['error'], 0);
        return array(7, $self['error'] . "\n");
    }
    // Return the success notice
    $self['error'] = "INFO => Domain ADDED: {$domain_name}";
    printmsg($self['error'], 0);
    return array(0, $self['error'] . "\n");
}
Example #15
0
function interface_modify($options = "")
{
    global $conf, $self, $onadb;
    printmsg("DEBUG => interface_modify({$options}) called", 3);
    // Version - UPDATE on every edit!
    $version = '1.11';
    // Parse incoming options string to an array
    $options = parse_options($options);
    // Set options[use_primary] to N if they're not set
    $options['use_primary'] = sanitize_YN($options['use_primary'], 'N');
    // Set options[force] to N if it's not set
    $options['force'] = sanitize_YN($options['force'], 'N');
    // Return the usage summary if we need to
    if ($options['help'] or !$options['interface'] and !$options['host'] or !$options['set_ip'] and !$options['set_mac'] and !$options['set_description'] and !$options['set_last_response'] and !$options['set_name']) {
        // NOTE: Help message lines should not exceed 80 characters for proper display on a console
        $self['error'] = 'ERROR => Insufficient parameters';
        return array(1, <<<EOM

interface_modify-v{$version}
Modify an interface record

  Synopsis: interface_modify [KEY=VALUE] ...

  Required:
    interface=ID or IP or MAC     interface ID or IP address
     or
    host=NAME[.DOMAIN] or ID      find interface by hostname or host_id

    set_ip=IP                     change IP address (numeric or dotted format)
    set_mac=ADDRESS               change the mac address (most formats ok)
    set_name=NAME                 interface name (i.e. "FastEthernet0/1.100")
    set_description=TEXT          description (i.e. "VPN link to building 3")
    set_last_response=DATE        date ip was last seen

  Optional:
    use_primary[=Y]               use the host's primary interface (only applies
                                  when "host" option is used!). NOTE: dcm.pl
                                  requires a value ("Y").


EOM
);
    }
    // They provided a interface ID, IP address, interface name, or MAC address
    if ($options['interface']) {
        // Find an interface record by something in that interface's record
        list($status, $rows, $interface) = ona_find_interface($options['interface']);
    } else {
        if ($options['host']) {
            // Find a host by the user's input
            list($status, $rows, $host) = ona_find_host($options['host']);
            if (!$host['id']) {
                printmsg("DEBUG => Host not found ({$options['host']})!", 3);
                $self['error'] = "ERROR => Host not found ({$options['host']})!";
                return array(2, $self['error'] . "\n");
            }
            // If we got one, load an associated interface
            // ... or the primary interface, if the use_primary option is present
            if ($options['use_primary'] == 'Y') {
                list($status, $rows, $interface) = ona_get_interface_record(array('id' => $host['primary_interface_id']));
            } else {
                list($status, $rows, $interface) = ona_get_interface_record(array('host_id' => $host['id']));
                if ($rows > 1) {
                    printmsg("DEBUG => Specified host ({$options['host']}) has more than one interface!", 3);
                    $self['error'] = "ERROR => Specified host ({$options['host']}) has more than one interface!";
                    return array(3, $self['error'] . "\n");
                }
            }
        }
    }
    // If we didn't get a record then exit
    if (!$interface or !$interface['id']) {
        printmsg("DEBUG => Interface not found ({$options['interface']})!", 3);
        $self['error'] = "ERROR => Interface not found ({$options['interface']})!";
        return array(4, $self['error'] . "\n");
    }
    // This array will contain the updated info we'll insert into the DB
    $SET = array();
    // Setting an IP address?
    if ($options['set_ip']) {
        $options['set_ip'] = trim($options['set_ip']);
        $orig_ip = $options['set_ip'];
        $options['set_ip'] = ip_mangle($options['set_ip'], 'numeric');
        if ($options['set_ip'] == -1) {
            printmsg("DEBUG => Invalid IP address ({$orig_ip})", 3);
            $self['error'] = "ERROR => Invalid IP address ({$orig_ip})";
            return array(5, $self['error'] . "\n");
        }
        // Validate that there isn't already another interface with the same IP address
        list($status, $rows, $record) = ona_get_interface_record("ip_addr = {$options['set_ip']}");
        if ($rows and $record['id'] != $interface['id']) {
            printmsg("DEBUG => IP conflict: That IP address (" . ip_mangle($orig_ip, 'dotted') . ") is already in use!", 3);
            $self['error'] = "ERROR => IP conflict: specified IP (" . ip_mangle($orig_ip, 'dotted') . ") is already in use!";
            return array(6, $self['error'] . "\nINFO => Conflicting interface record ID: {$record['ID']}\n");
        }
        // Since the IP seems available, let's double check and make sure it's not in a DHCP address pool
        list($status, $rows, $pool) = ona_get_dhcp_pool_record("ip_addr_start <= '{$options['set_ip']}' AND ip_addr_end >= '{$options['set_ip']}'");
        if ($status or $rows) {
            printmsg("DEBUG => IP conflict: That IP address (" . ip_mangle($orig_ip, 'dotted') . ") falls within a DHCP address pool!", 3);
            $self['error'] = "ERROR => IP conflict: That IP address (" . ip_mangle($orig_ip, 'dotted') . ") falls within a DHCP address pool!";
            return array(5, $self['error'] . "\n" . "INFO => Conflicting DHCP pool record ID: {$pool['id']}\n");
        }
        // Find the Subnet (network) ID to use from the IP address
        list($status, $rows, $subnet) = ona_find_subnet(ip_mangle($options['set_ip'], 'dotted'));
        if ($status or !$rows) {
            printmsg("DEBUG => That IP address (" . ip_mangle($orig_ip, 'dotted') . ") is not inside a defined subnet!", 3);
            $self['error'] = "ERROR => That IP address (" . ip_mangle($orig_ip, 'dotted') . ") is not inside a defined subnet!";
            return array(7, $self['error'] . "\n");
        }
        // Validate that the IP address supplied isn't the base or broadcast of the subnet
        if (is_ipv4($options['set_ip']) && $options['set_ip'] == $subnet['ip_addr'] || !is_ipv4($options['set_ip']) && !gmp_cmp(gmp_init($options['set_ip']), gmp_init($subnet['ip_addr']))) {
            printmsg("DEBUG => IP address (" . ip_mangle($orig_ip, 'dotted') . ") can't be a subnet's base address!", 3);
            $self['error'] = "ERROR => IP address (" . ip_mangle($orig_ip, 'dotted') . ") can't be a subnet's base address!";
            return array(8, $self['error'] . "\n");
        }
        if (is_ipv4($options['set_ip']) && $options['set_ip'] == 4294967295 - $subnet['ip_mask'] + $subnet['ip_addr'] || !is_ipv4($options['set_ip']) && !gmp_cmp(gmp_init($options['set_ip']), gmp_add(gmp_init($subnet['ip_addr']), gmp_sub("340282366920938463463374607431768211455", $subnet['ip_mask'])))) {
            printmsg("DEBUG => IP address (" . ip_mangle($orig_ip, 'dotted') . ") can't be a subnet's broadcast address!", 3);
            $self['error'] = "ERROR => IP address (" . ip_mangle($orig_ip, 'dotted') . ") can't be the subnet broadcast address!";
            return array(9, $self['error'] . "\n");
        }
        // Allow some overrides.
        if ($options['force'] != 'Y') {
            // Search for any existing interfaces on the same subnet
            //            list($status, $rows, $record) = ona_get_interface_record(array('subnet_id' => $subnet['id'],
            //                                                                            'host_id'    => $interface['host_id']));
            // Check to be sure we don't exceed maximum lengths
            if (strlen($options['name']) > 255) {
                $self['error'] = "ERROR => 'name' exceeds maximum length of 255 characters.";
                return array(2, $self['error'] . "\n" . "NOTICE => You may ignore this error and add the interface anyway with the \"force=yes\" option.\n");
            }
            if (strlen($options['description']) > 255) {
                $self['error'] = "ERROR => 'description' exceeds maximum length of 255 characters.";
                return array(2, $self['error'] . "\n" . "NOTICE => You may ignore this error and add the interface anyway with the \"force=yes\" option.\n");
            }
        }
        // Make sure we update the ptr record domain if needed.
        // MP: TODO: would it be better to run the dns_modify module vs doing a direct db_update_record???
        $ipflip = ip_mangle($options['set_ip'], '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);
        if (isset($ptrdomain['id'])) {
            list($status, $rows, $dnsrec) = ona_get_dns_record(array('type' => 'PTR', 'interface_id' => $interface['id']));
            // If the new ptrdomain does not match an existing ptr records domain then we need to change it.
            if ($rows > 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' => date('Y-m-j G:i:s')));
                if ($status or !$rows) {
                    $self['error'] = "ERROR => interface_modify() PTR record domain update failed: " . $self['error'];
                    printmsg($self['error'], 0);
                    return array(14, $self['error'] . "\n");
                }
            }
        }
        // TRIGGER: Since we are changing the IP of an interface that dns records may point to, we need to loop through them all
        if ($interface['ip_addr'] != $options['set_ip']) {
            // Get all the DNS records using this interface ID
            list($status, $rows, $records) = db_get_records($onadb, 'dns', array('interface_id' => $interface['id']));
            // Loop them and set their domains for rebuild
            foreach ($records as $record) {
                list($status, $rows) = db_update_record($onadb, 'dns_server_domains', array('domain_id' => $record['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");
                }
            }
        }
        // Check permissions
        //         if (!authlvl($subnet['LVL'])) {
        //             $self['error'] = "Permission denied!";
        //             printmsg($self['error'], 0);
        //             return(array(13, $self['error'] . "\n"));
        //         }
        // Everything looks ok, add it to $SET
        if ($interface['subnet_id'] != $subnet['id']) {
            $SET['subnet_id'] = $subnet['id'];
        }
        if ($interface['ip_addr'] != $options['set_ip']) {
            $SET['ip_addr'] = $options['set_ip'];
        }
    }
    // Setting an MAC address?
    if (array_key_exists('set_mac', $options)) {
        if ($options['set_mac']) {
            // allow null mac addresses (to unset one for example)
            $options['set_mac'] = trim($options['set_mac']);
            $orig_mac = $options['set_mac'];
            $options['set_mac'] = mac_mangle($options['set_mac'], 1);
            if ($options['set_mac'] == -1) {
                printmsg("DEBUG => The MAC address specified ({$orig_mac}) is invalid!", 3);
                $self['error'] = "ERROR => The MAC address specified ({$orig_mac}) is invalid!";
                return array(11, $self['error'] . "\n");
            }
            // Unless they have opted to allow duplicate mac addresses ...
            if ($options['force'] != 'Y') {
                // Validate that there isn't already another interface with the same MAC address on another host
                // Assume duplicate macs on the same host are ok
                list($status, $rows, $record) = db_get_record($onadb, 'interfaces', "mac_addr LIKE '{$options['set_mac']}' AND host_id != {$interface['host_id']}");
                if ($rows and $record['id'] != $interface['id'] or $rows > 1) {
                    printmsg("DEBUG => MAC conflict: That MAC address ({$options['set_mac']}) is already in use on another host!", 3);
                    $self['error'] = "ERROR => MAC conflict: That MAC address ({$options['set_mac']}) is already in use on another host!";
                    return array(12, $self['error'] . "\n" . "NOTICE => You may ignore this error and update the interface anyway with the \"force=yes\" option.\n" . "INFO => Conflicting interface record ID: {$record['id']}\n");
                }
            }
        }
        if ($interface['mac_addr'] != $options['set_mac']) {
            $SET['mac_addr'] = $options['set_mac'];
        }
    }
    // Check the date formatting etc
    if (isset($options['set_last_response'])) {
        // format the time that was passed in for the database
        $SET['last_response'] = date('Y-m-j G-i-s', strtotime($options['set_last_response']));
    }
    // Set options[set_name]?
    if (array_key_exists('set_name', $options) && $interface['name'] != $options['set_name']) {
        $SET['name'] = trim($options['set_name']);
    }
    // Set options[set_description]?
    if (array_key_exists('set_description', $options) && $interface['description'] != $options['set_description']) {
        $SET['description'] = $options['set_description'];
    }
    // Check permissions
    list($status, $rows, $host) = ona_find_host($interface['host_id']);
    if (!auth('interface_modify')) {
        $self['error'] = "Permission denied!";
        printmsg($self['error'], 0);
        return array(13, $self['error'] . "\n");
    }
    // Get the interface record before updating (logging)
    list($status, $rows, $original_interface) = ona_get_interface_record(array('id' => $interface['id']));
    // Update the interface record
    if (count($SET) > 0) {
        list($status, $rows) = db_update_record($onadb, 'interfaces', array('id' => $interface['id']), $SET);
        if ($status or !$rows) {
            $self['error'] = "ERROR => interface_modify() SQL Query failed: " . $self['error'];
            printmsg($self['error'], 0);
            return array(14, $self['error'] . "\n");
        }
    }
    // Get the interface record after updating (logging)
    list($status, $rows, $new_interface) = ona_get_interface_record(array('id' => $interface['id']));
    list($status, $rows, $new_int) = ona_find_interface($interface['id']);
    // Return the success notice
    $text = format_array($SET);
    $self['error'] = "INFO => Interface UPDATED:{$interface['id']}: {$new_int['ip_addr_text']}";
    $log_msg = "INFO => Interface UPDATED:{$interface['id']}:{$new_int['ip_addr_text']}: ";
    $more = "";
    foreach (array_keys($original_interface) as $key) {
        if ($original_interface[$key] != $new_interface[$key]) {
            $log_msg .= $more . $key . "[" . $original_interface[$key] . "=>" . $new_interface[$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{$text}\n");
}