Ejemplo n.º 1
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");
}
Ejemplo n.º 2
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();
}
Ejemplo n.º 3
0
function ws_save($window_name, $form = '')
{
    global $include, $conf, $self, $onadb;
    // Check permissions
    if (!(auth('dns_record_modify') and auth('dns_record_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_domain'] == '' or
    //         $form['set_type'] == ''
    //        ) {
    //         $response->addScript("alert('Please complete all fields to continue!');");
    //         return($response->getXML());
    //     }
    // we need to do a little validation here to make sure things
    // have a good chance of working!
    // If the name we were passed has a leading . in it then remove the dot.
    $form['set_name'] = preg_replace("/^\\./", '', trim($form['set_name']));
    $form['set_ip'] = trim($form['set_ip']);
    // Validate the "set_name" name is valid
    if ($form['set_name'] and $form['set_type'] != 'NS') {
        $form['set_name'] = sanitize_hostname($form['set_name']);
        if (!$form['set_name']) {
            $response->addScript("alert('Invalid hostname!');");
            return $response->getXML();
        }
    }
    // Make sure the IP address specified is valid
    if ($form['set_name'] != '.' 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();
        }
    }
    $form['set_addptr'] = sanitize_YN($form['set_addptr'], 'N');
    // Set the effective date to 0 to disable
    if ($form['disable']) {
        $form['set_ebegin'] = 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['dns_id']) {
        $module = 'add';
        // options
        $form['domain'] = $form['set_domain'];
        $form['name'] = $form['set_name'] . '.' . $form['set_domain'];
        unset($form['set_name']);
        unset($form['set_domain']);
        $form['type'] = $form['set_type'];
        unset($form['set_type']);
        $form['ebegin'] = $form['set_ebegin'];
        unset($form['set_ebegin']);
        $form['notes'] = $form['set_notes'];
        unset($form['set_notes']);
        $form['ip'] = $form['set_ip'];
        unset($form['set_ip']);
        $form['ttl'] = $form['set_ttl'];
        unset($form['set_ttl']);
        $form['addptr'] = $form['set_addptr'];
        unset($form['set_addptr']);
        $form['view'] = $form['set_view'];
        unset($form['set_view']);
        // if this is a cname. then set the pointsto option
        if ($form['type'] == 'CNAME' or $form['type'] == 'MX' or $form['type'] == 'NS' or $form['type'] == 'SRV') {
            $form['pointsto'] = $form['set_pointsto'];
        }
        if ($form['type'] == 'MX') {
            $form['mx_preference'] = $form['set_mx_preference'];
        }
        if ($form['type'] == 'TXT') {
            $form['txt'] = $form['set_txt'];
        }
        if ($form['type'] == 'SRV') {
            $form['srv_pri'] = $form['set_srv_pri'];
        }
        if ($form['type'] == 'SRV') {
            $form['srv_weight'] = $form['set_srv_weight'];
        }
        if ($form['type'] == 'SRV') {
            $form['srv_port'] = $form['set_srv_port'];
        }
        // If it is an NS record, blank the name out
        //if ($form['type'] == 'NS') $form['name'] = $form['set_domain'];
        // If we are adding a PTR.. switch existing a record to name
        if ($form['type'] == 'PTR') {
            $form['name'] = $form['set_pointsto'];
        }
        // If there's no "refresh" javascript, add a command to view the new dns record
        if (!preg_match('/\\w/', $form['js'])) {
            $form['js'] = "xajax_window_submit('work_space', 'xajax_window_submit(\\'display_host\\', \\'host=>{$form['name']}\\', \\'display\\')');";
        }
    } else {
        $form['set_name'] .= '.' . $form['set_domain'];
        //FIXME: MP temporary kludge to get around not having a proper find_dns_record module.. ID is the only way to find a record now and it is done via the name field
        $form['name'] = $form['dns_id'];
        // if this is a cname. then set the pointsto option
        if ($form['set_type'] != 'CNAME') {
            $form['set_pointsto'] == '';
        }
    }
    // Run the module to ADD the DNS record, or MODIFY THE DNS record.
    list($status, $output) = run_module('dns_record_' . $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 they have checked the keep adding records box then dont remove the window
        if (!$form['keepadding']) {
            $js .= "removeElement('{$window_name}');";
        } else {
            $js .= "el('statusinfo_{$window_name}').innerHTML = 'Previously added:<br>{$form['name']} Type: {$form['type']}';";
        }
        if ($form['js']) {
            $js .= $form['js'];
        }
    }
    // Insert the new table into the window
    $response->addScript($js);
    return $response->getXML();
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
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");
}