function add_permission($options = "") { global $conf, $self, $onadb; printmsg('DEBUG => add_permission(' . $options . ') called', 3); // Version - UPDATE on every edit! $version = '1.00'; // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !$options['name']) { $self['error'] = 'ERROR => Insufficient parameters'; // NOTE: Help message lines should not exceed 80 characters for proper display on a console return array(1, <<<EOM add_permission-v{$version} Registers a new permission, this should be used by install scripts that are creating new functionality that requires a registered permission. Synopsis: add_permission(OPTIONS) Options: name=STRING Name of permission desc=STRING Quoted string to describe this permission EOM ); } // Get a list of the valid "permissions" and their descriptions. list($status, $rows, $permissions) = db_get_record($onadb, 'permissions', array('name' => $options['name']), ''); if ($rows) { $self['error'] = "ERROR => add_permission() Permission already exists: {$options['name']}"; printmsg($self['error'], 0); return array(1, $self['error'] . "\n"); } // Get the next ID for the new host record $id = ona_get_next_id('permissions'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id('permissions') call failed!"; printmsg($self['error'], 0); return array(7, $self['error'] . "\n"); } printmsg("DEBUG => ID for new permission record: {$id}", 3); // Add the record list($status, $rows) = db_insert_record($onadb, 'permissions', array('id' => $id, 'name' => $options['name'], 'description' => $options['desc'])); if ($status or !$rows) { $self['error'] = "ERROR => add_permission() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(2, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => Permission ADDED: {$options['name']} [{$options['desc']}]"; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
function dhcp_server_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.01'; printmsg("DEBUG => dhcp_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['subnet'] 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 dhcp_server_add-v{$version} Assigns an existing subnet record to a DHCP server Synopsis: dhcp_server_add [KEY=VALUE] ... Required: subnet=NAME or ID subnet name or ID server=NAME[.DOMAIN] or ID server name or ID Notes: DOMAIN will default to {$conf['dns_defaultdomain']} if not specified EOM ); } // Determine the entry itself exists list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); // Test to see that we were able to find the specified record if (!$subnet['id']) { printmsg("DEBUG => Unable to find the subnet record using {$options['subnet']}!", 3); $self['error'] = "ERROR => Unable to find the subnet record using {$options['subnet']}!"; return array(4, $self['error'] . "\n"); } printmsg("DEBUG => dhcp_server_add(): Found subnet, {$subnet['name']}", 3); // Determine the server is valid list($status, $rows, $host) = ona_find_host($options['server']); 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"); } // Check permissions if (!auth('advanced') or !authlvl($host['LVL']) or !authlvl($subnet['LVL'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(12, $self['error'] . "\n"); } // Test that this subnet isnt already assigned to the server list($status, $rows, $dhcpserver) = ona_get_dhcp_server_subnet_record(array('host_id' => $host['id'], 'subnet_id' => $subnet['id'])); if ($rows) { printmsg("DEBUG => Subnet {$subnet['name']} already assigned to {$host['fqdn']}", 3); $self['error'] = "ERROR => Subnet {$subnet['name']} already assigned to {$host['fqdn']}"; return array(11, $self['error'] . "\n"); } // Get the next ID $id = ona_get_next_id('dhcp_server_subnets'); 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 => dhcp_server_add(): New dhcp server subnet ID: {$id}", 3); // Add new record to dhcp_server_subnets_b list($status, $rows) = db_insert_record($onadb, 'dhcp_server_subnets', array('id' => $id, 'host_id' => $host['id'], 'subnet_id' => $subnet['id'])); if ($status or !$rows) { $self['error'] = "ERROR => dhcp_server_add() SQL Query failed:" . $self['error']; printmsg($self['error'], 0); return array(8, $add_to_error . $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => DHCP Subnet/Server Pair ADDED: {$subnet['name']}/{$host['fqdn']} "; printmsg($self['error'], 0); return array(0, $add_to_error . $self['error'] . "\n"); }
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); }
function ws_save($window_name, $form = '') { global $conf, $self, $onadb; // Check permissions if (!auth('advanced')) { $response = new xajaxResponse(); $response->addScript("alert('Permission denied!');"); return $response->getXML(); } // Instantiate the xajaxResponse object $response = new xajaxResponse(); $js = ''; // Strip whitespace // FIXME: (PK) What about SQL injection attacks? This is a user-entered string... $form['cust_attrib_type_name'] = trim($form['cust_attrib_type_name']); // Don't insert a string of all white space! if ($form['cust_attrib_type_name'] == "") { $self['error'] = "ERROR => Blank names not allowed."; printmsg($self['error'], 0); $response->addScript("alert('{$self['error']}');"); return $response->getXML(); } // If you get a numeric in $form, update the record if (is_numeric($form['id'])) { // Get the manufacturer record before updating (logging) list($status, $rows, $original_manufacturer) = ona_get_custom_attribute_type_record(array('id' => $form['id'])); if ($form['cust_attrib_type_name'] !== $original_type['name']) { list($status, $rows) = db_update_record($onadb, 'custom_attribute_types', array('id' => $form['id']), array('name' => $form['cust_attrib_type_name'], 'field_validation_rule' => $form['field_validation_rule'], 'failed_rule_text' => $form['failed_rule_text'], 'notes' => $form['notes'])); if ($status or !$rows) { $self['error'] = "ERROR => cust_attrib_type edit update ws_save() failed: " . $self['error']; printmsg($self['error'], 0); $response->addScript("alert('{$self['error']}');"); } else { // Get the manufacturer record after updating (logging) list($status, $rows, $new_type) = ona_get_custom_attribute_type_record(array('id' => $form['id'])); // Return the success notice $self['error'] = "INFO => Custom Attribute Type UPDATED:{$new_type['id']}: {$new_type['name']}"; printmsg($self['error'], 0); $log_msg = "INFO => Custom Attribute Type UPDATED:{$new_type['id']}: name[{$original_type['name']}=>{$new_type['name']}]"; printmsg($log_msg, 0); } } } else { $id = ona_get_next_id('custom_attribute_types'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id('custom_attribute_types') call failed!"; printmsg($self['error'], 0); } else { list($status, $rows) = db_insert_record($onadb, "custom_attribute_types", array('id' => $id, 'name' => $form['cust_attrib_type_name'], 'field_validation_rule' => $form['field_validation_rule'], 'failed_rule_text' => $form['failed_rule_text'], 'notes' => $form['notes'])); if ($status or !$rows) { $self['error'] = "ERROR => Custom attribute type add ws_save() failed: " . $self['error']; printmsg($self['error'], 0); } else { $self['error'] = "INFO => Custom Attribute Type ADDED: {$form['cust_attrib_type_name']} "; printmsg($self['error'], 0); } } } // If the module returned an error code display a popup warning if ($status or !$rows) { $js .= "alert(\"Save failed. " . trim($self['error']) . " (Hint: Does the name you're trying to insert already exist?)\");"; } else { $js .= "removeElement('{$window_name}');"; $js .= "xajax_window_submit('app_custom_attribute_type_list', xajax.getFormValues('app_custom_attribute_type_list_filter_form'), 'display_list');"; } // Return some javascript to the browser $response->addScript($js); return $response->getXML(); }
function ws_save($window_name, $form = '') { global $conf, $self, $onadb; // Check permissions if (!auth('advanced')) { $response = new xajaxResponse(); $response->addScript("alert('Permission denied!');"); return $response->getXML(); } // Instantiate the xajaxResponse object $response = new xajaxResponse(); $js = ''; // If you get a numeric in $form, update the record if (is_numeric($form['id'])) { // Get the option record before updating (logging) list($status, $rows, $original_option) = ona_get_dhcp_option_record(array('id' => $form['id'])); list($status, $rows) = db_update_record($onadb, 'dhcp_options', array('id' => $form['id']), array('display_name' => $form['display_name'], 'type' => $form['type'], 'number' => $form['number'], 'name' => $form['name'])); if ($status or !$rows) { $self['error'] = "ERROR => dhcp_option update ws_save() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); } else { // Get the record after updating (logging) list($status, $rows, $new_option) = ona_get_dhcp_option_record(array('id' => $form['id'])); // Return the success notice $self['error'] = "INFO => DHCP Option UPDATED:{$new_option['id']}: {$new_option['name']}"; $log_msg = "INFO => DHCP Option UPDATED:{$new_option['id']}: "; $more = ""; foreach (array_keys($original_option) as $key) { if ($original_option[$key] != $new_option[$key]) { $log_msg .= $more . $key . "[" . $original_option[$key] . "=>" . $new_option[$key] . "]"; $more = ";"; } } // only print to logfile if a change has been made to the record if ($more != '') { printmsg($self['error'], 0); printmsg($log_msg, 0); } } } else { $id = ona_get_next_id('dhcp_options'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); } else { printmsg("DEBUG => ID for new dhcp option: {$id}", 3); list($status, $rows) = db_insert_record($onadb, "dhcp_options", array('id' => $id, 'display_name' => $form['display_name'], 'type' => $form['type'], 'number' => $form['number'], 'name' => $form['name'])); if ($status or !$rows) { $self['error'] = "ERROR => dhcp_option_edit add ws_save() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); } else { $self['error'] = "INFO => DHCP Option ADDED: {$form['name']} "; printmsg($self['error'], 0); } } } // If the module returned an error code display a popup warning if ($status) { $js .= "alert('Save failed. " . trim($self['error']) . " (Hint: All fields are required!)');"; } else { $js .= "removeElement('{$window_name}');"; $js .= "xajax_window_submit('app_dhcp_option_list', xajax.getFormValues('app_dhcp_option_list_filter_form'), 'display_list');"; } // Return some javascript to the browser $response->addScript($js); return $response->getXML(); }
function ws_save($window_name, $form = '') { global $conf, $self, $onadb; // Check permissions if (!auth('advanced')) { $response = new xajaxResponse(); $response->addScript("alert('Permission denied!');"); return $response->getXML(); } // Instantiate the xajaxResponse object $response = new xajaxResponse(); $js = ''; // If you get a numeric in $form, update the record if (is_numeric($form['id'])) { // Get the device type record before updating (logging) list($status, $rows, $original_type) = ona_get_device_type_record(array('id' => $form['id'])); list($status, $rows) = db_update_record($onadb, 'device_types', array('id' => $form['id']), array('model_id' => $form['model_id'], 'role_id' => $form['role_id'])); if ($status or !$rows) { $self['error'] = "ERROR => device_type_edit update ws_save() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); } else { // Return the success notice $self['error'] = "INFO => Device Type UPDATED:{$original_type['id']}"; printmsg($self['error'], 0); // $self['error'] = "INFO => Device Type UPDATED:{$original_type['id']}: DEVICE_TYPE_DESCRIPTION[{$original_type['DEVICE_TYPE_DESCRIPTION']}=>{$form['device_type_description']}]"; // printmsg($self['error'], 0); } } else { $id = ona_get_next_id('device_types'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); } else { printmsg("DEBUG => id for new device type: {$id}", 3); list($status, $rows) = db_insert_record($onadb, 'device_types', array('id' => $id, 'model_id' => $form['model_id'], 'role_id' => $form['role_id'])); if ($status or !$rows) { $self['error'] = "ERROR => device_type_edit add ws_save() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); } else { $self['error'] = "INFO => Device Type ADDED: {$form['id']} "; printmsg($self['error'], 0); } } } // If the module returned an error code display a popup warning if ($status) { $js .= "alert('Save failed. " . trim($self['error']) . " (Hint: All fields are required!)');"; } else { $js .= "removeElement('{$window_name}');"; $js .= "xajax_window_submit('app_device_type_list', xajax.getFormValues('app_device_type_list_filter_form'), 'display_list');"; } // Return some javascript to the browser $response->addScript($js); return $response->getXML(); }
function config_add($options = "") { // The important globals global $conf; global $self; global $onadb; // Version - UPDATE on every edit! $version = '1.00'; // This debug is set very high as it can contain large configs and sensitive data, you gotta mean it! printmsg('DEBUG => config_add(' . $options . ') called', 7); // 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['config'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console return array(1, <<<EOM config_add-v{$version} Adds a new config text record into the database Synopsis: config_add [KEY=VALUE] ... Required: config=TEXT the actual config text or filename to insert host=ID or NAME[.DOMAIN] host the config text is from type=TYPE type of config text we're inserting - usually "IOS_VERSION" or "IOS_CONFIG" EOM ); } // Search for the host first list($status, $rows, $host) = ona_find_host($options['host']); // Error if the host doesn't exist if (!$host['id']) { $self['error'] = "ERROR => The host specified, {$options['host']}, does not exist!"; return array(2, $self['error']); } // Now find the ID of the config type they entered list($status, $rows, $config_type) = ona_get_config_type_record(array('name' => $options['type'])); if (!$config_type['id']) { $self['error'] = "ERROR => The config type specified, {$options['type']}, is invalid!"; return array(3, $self['error']); } $options['config'] = preg_replace('/\\\\"/', '"', $options['config']); $options['config'] = preg_replace('/\\\\=/', '=', $options['config']); // Get the next ID for the new config_text record $id = ona_get_next_id('configurations'); if (!$id) { return array(4, "ERROR => The ona_get_next_id(configurations) call failed!\n"); } printmsg("DEBUG => ID for new config_record: {$id}", 3); // Add the config_text list($status, $rows) = db_insert_record($onadb, 'configurations', array('id' => $id, 'configuration_type_id' => $config_type['id'], 'host_id' => $host['id'], 'md5_checksum' => md5($options['config']), 'config_body' => $options['config'])); if ($status or !$rows) { $self['error'] = "ERROR => message_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } list($status, $rows, $record) = ona_get_config_record(array('id' => $id)); if ($status or !$rows) { $self['error'] = 'ERROR => SQL INSERT failed. Database error: ' . $error . "\n"; return array(5, $self['error']); } // Return the success notice $text = "NOTICE => Config text record ADDED, ID: {$id}\n"; return array(0, $text); }
function dns_record_add($options = "") { global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.11'; printmsg("DEBUG => dns_record_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['name'] and $options['type'])) { // 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_add-v{$version} Add a new DNS record Synopsis: dns_record_add [KEY=VALUE] ... Required: name=NAME[.DOMAIN] hostname for new DNS record type=TYPE record type (A,CNAME,PTR...) Optional: notes=NOTES textual notes ip=ADDRESS ip address (numeric or dotted) ttl=NUMBER time in seconds, defaults to ttl from domain pointsto=NAME[.DOMAIN] hostname that a CNAME,NS,MX etc points to addptr auto add a PTR record when adding A records mx_preference=NUMBER preference for the MX record txt=STRING text value of a TXT record srv_pri=NUMBER SRV Priority srv_weight=NUMBER SRV Weight srv_port=NUMBER SRV Port ebegin=date Set the begin date for record, 0 disables, default now domain=DOMAIN use only if you need to explicitly set a parent domain view=STRING DNS view identifier. AKA Split horizon. Examples: dns_record_add name=newhost.something.com type=A ip=10.1.1.2 addptr dns_record_add name=somedomain.com type=NS pointsto=ns.somedomain.com dns_record_add name=cname.domain.com type=CNAME pointsto=host.domain.com dns_record_add name=host.something.com type=TXT txt="my text value" dns_record_add name=domain.com type=MX pointsto=mxhost.domain.com mx_preference=10 dns_record_add name=_foo._tcp.example.com type=SRV pointsto=host.domain.com srv_port=80 dns_record_add name=newhost.something.com type=PTR ip=10.1.1.10 DOMAIN will default to {$conf['dns_defaultdomain']} if not specified. EOM ); } /* thoughts on the flow of things: a records: check if there is an A record with that name/domain and IP already. check that name/domain does not match a CNAME entry will not have a dns_id value.. blank it out if autoptr is set, create a ptr record too cname records: check that name/domain does not match an A entry check that name/domain does not match an CNAME entry name/domain and dns_id columns must be unique---< implied by the previous check of no cnames using this name do I need interface_id??????, yes its used to assoicate it with the host. this will come via the A record it points to via a lookup ptr records: must be unique in interface_id column, ie. one PTR per interface/ip FIXME: do some validation of the different options, pointsto only with cname type etc etc FIXME: what about when you add an entry with a name that matches a primary dns record that already exists. while adding multiple A records that have the same name is ok, its not really a good thing to have the primary name for a host be duplicated. the primary name for a host should be unique in all cases I'm aware of */ // 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['pointsto'] = trim($options['pointsto']); $options['name'] = trim($options['name']); $options['domain'] = trim($options['domain']); $options['txt'] = trim($options['txt']); $options['view'] = trim($options['view']); // Check the date formatting etc if (isset($options['ebegin'])) { // format the time that was passed in for the database, leave it as 0 if they pass it as 0 $options['ebegin'] = $options['ebegin'] == '0' ? 0 : date('Y-m-j G:i:s', strtotime($options['ebegin'])); } else { // If I got no date, use right now as the date/time $options['ebegin'] = date('Y-m-j G:i:s'); } // Switch the type setting to uppercase $options['type'] = strtoupper($options['type']); $add_txt = ''; $add_mx_preference = ''; $add_srv_pri = ''; $add_srv_weight = ''; $add_srv_port = ''; // force AAAA to A to keep it consistant.. we'll display it properly as needed if ($options['type'] == 'AAAA') { $options['type'] = 'A'; } // If the name we were passed has a leading or trailing . in it then remove the dot. $options['name'] = preg_replace("/^\\./", '', $options['name']); $options['name'] = preg_replace("/\\.\$/", '', $options['name']); // Determine the real hostname and domain name 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. // // 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['name'], 0); } // Find the domain name piece of $search. if (!isset($domain['id'])) { printmsg("ERROR => Unable to determine domain name portion of ({$options['name']})!", 3); $self['error'] = "ERROR => Unable to determine domain name portion of ({$options['name']})!"; return array(3, $self['error'] . "\n"); } printmsg("DEBUG => ona_find_domain({$options['name']}) returned: {$domain['fqdn']}", 3); // Now find what the host part of $search is $hostname = str_replace(".{$domain['fqdn']}", '', $options['name']); // Validate that the DNS name has only valid characters in it $hostname = sanitize_hostname($hostname); if (!$hostname) { printmsg("ERROR => Invalid host name ({$options['name']})!", 3); $self['error'] = "ERROR => Invalid host name ({$options['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} Domainname: {$domain['fqdn']}, Domain ID: {$domain['id']}", 3); // If we are using anything but in-addr.arpa for PTR or NS records, fail out! if ((strpos($domain['fqdn'], "ip6.arpa") or strpos($domain['fqdn'], "in-addr.arpa")) and $options['type'] != 'PTR' and $options['type'] != 'NS') { printmsg("ERROR => Only PTR and NS records should use in-addr.arpa or ip6.arpa domains!", 3); $self['error'] = "ERROR => Only PTR and NS records should use in-addr.arpa or ip6.arpa domains!"; return array(4, $self['error'] . "\n"); } // Gather DNS view information $add_pointsto_viewid = $add_viewid = 0; if ($options['view']) { if (is_numeric($options['view'])) { $viewsearch = array('id' => $options['view']); } else { $viewsearch = array('name' => strtoupper($options['view'])); } // find the view record, list($status, $rows, $dnsview) = ona_get_dns_view_record($viewsearch); if (!$rows) { printmsg("ERROR => dns_record_add() Unable to find DNS view: {$options['view']}", 3); $self['error'] = "ERROR => dns_record_add() Unable to find DNS view: {$options['view']}."; return array(4, $self['error'] . "\n"); } $add_pointsto_viewid = $add_viewid = $dnsview['id']; } // lets test out if it has a / in it to strip the view name portion if (strstr($options['pointsto'], '/')) { list($dnsview, $options['pointsto']) = explode('/', $options['pointsto']); list($status, $rows, $view) = db_get_record($onadb, 'dns_views', array('name' => strtoupper($dnsview))); if ($rows) { $add_pointsto_viewid = $view['id']; } } // 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.'; } // Process A or AAAA record types if ($options['type'] == 'A' or $options['type'] == 'AAAA') { // find the IP interface record, list($status, $rows, $interface) = ona_find_interface($options['ip']); if (!$rows) { printmsg("ERROR => dns_record_add() Unable to find existing IP interface: {$options['ip']}", 3); $self['error'] = "ERROR => dns_record_add() Unable to find IP interface: {$options['ip']}. A records must point to existing IP addresses. Please add an interface with this IP address first."; return array(4, $self['error'] . "\n"); } // Validate that there isn't already any dns record named $hostname in the domain $domain_id. list($d_status, $d_rows, $d_record) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'interface_id' => $interface['id'], 'type' => 'A', 'dns_view_id' => $add_viewid)); if ($d_status or $d_rows) { printmsg("ERROR => Another DNS A record named {$hostname}.{$domain['fqdn']} with IP {$interface['ip_addr_text']} already exists!{$viewmsg}", 3); $self['error'] = "ERROR => Another DNS A record named {$hostname}.{$domain['fqdn']} with IP {$interface['ip_addr_text']} already exists!{$viewmsg}"; return array(5, $self['error'] . "\n"); } // Validate that there are no CNAMES already with this fqdn list($c_status, $c_rows, $c_record) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'type' => 'CNAME', 'dns_view_id' => $add_viewid)); if ($c_rows or $c_status) { printmsg("ERROR => Another DNS CNAME record named {$hostname}.{$domain['fqdn']} already exists!{$viewmsg}", 3); $self['error'] = "ERROR => Another DNS CNAME record named {$hostname}.{$domain['fqdn']} already exists!{$viewmsg}"; return array(5, $self['error'] . "\n"); } $add_name = $hostname; $add_domainid = $domain['id']; $add_interfaceid = $interface['id']; // A records should not have parent dns records $add_dnsid = ''; // Dont print a dot unless hostname has a value if ($hostname) { $hostname = $hostname . '.'; } $info_msg = "{$hostname}{$domain['fqdn']} -> " . ip_mangle($interface['ip_addr'], 'dotted'); // Just to be paranoid, I'm doing the ptr checks here as well if addptr is set if ($options['addptr'] == 'Y') { // Check that no other PTR records are set up for this IP list($status, $rows, $record) = ona_get_dns_record(array('interface_id' => $interface['id'], 'type' => 'PTR', 'dns_view_id' => $add_viewid)); if ($rows) { printmsg("ERROR => Another DNS PTR record already exists for this IP interface!{$viewmsg}", 3); $self['error'] = "ERROR => Another DNS PTR record already exists for this IP interface!{$viewmsg}"; return array(5, $self['error'] . "\n"); } } } else { if ($options['type'] == 'PTR') { // find the IP interface record, list($status, $rows, $interface) = ona_find_interface($options['ip']); if (!$rows) { printmsg("ERROR => dns_record_add() Unable to find IP interface: {$options['ip']}", 3); $self['error'] = "ERROR => dns_record_add() Unable to find IP interface: {$options['ip']}. PTR records must point to existing IP addresses. Please add an interface with this IP address first."; return array(4, $self['error'] . "\n"); } // Check that no other PTR records are set up for this IP list($status, $rows, $record) = ona_get_dns_record(array('interface_id' => $interface['id'], 'type' => 'PTR', 'dns_view_id' => $add_viewid)); if ($rows) { printmsg("ERROR => Another DNS PTR record already exists for this IP interface!{$viewmsg}", 3); $self['error'] = "ERROR => Another DNS PTR record already exists for this IP interface!{$viewmsg}"; return array(5, $self['error'] . "\n"); } // Find the dns record that it will point to list($status, $rows, $arecord) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'interface_id' => $interface['id'], 'type' => 'A', 'dns_view_id' => $add_viewid)); if ($status or !$rows) { printmsg("ERROR => Unable to find DNS A record to point PTR entry to! Check that the IP you chose is associated with the name you chose.{$viewmsg}", 3); $self['error'] = "ERROR => Unable to find DNS A record to point PTR entry to! Check that the IP you chose is associated with the name you chose.{$viewmsg}"; // As a last resort just find a matching A record no matter the IP. // This is for PTRs that point to an A record that uses a different IP (loopback example) // MP: since there could be multiple A records, I'm going to fail out if there is not JUST ONE A record. // this is limiting in a way but allows cleaner data. list($status, $rows, $arecord) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'type' => 'A', 'dns_view_id' => $add_viewid)); if ($rows > 1) { printmsg("ERROR => Unable to find a SINGLE DNS A record to point PTR entry to! In this case, you are only allowed to do this if there is one A record using this name.{$viewmsg}", 3); $self['error'] = "ERROR => Unable to find a SINGLE DNS A record to point PTR entry to! In this case, you are only allowed to do this if there is one A record using this name.{$viewmsg}"; } if ($rows != 1) { return array(66, $self['error'] . "\n"); } } $ipflip = ip_mangle($interface['ip_addr'], '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, $rows, $ptrdomain) = ona_find_domain($ipflip . $arpa); // if (!$ptrdomain['id']) { // printmsg("ERROR => Unable to find a reverse pointer domain for this IP! Add at least the following DNS domain: {$octets[3]}.in-addr.arpa",3); // $self['error'] = "ERROR => Unable to find a reverse pointer domain for this IP! Add at least the following DNS domain: {$octets[3]}.in-addr.arpa"; // return(array(5, $self['error'] . "\n")); // } if (!$ptrdomain['id']) { printmsg("ERROR => This operation tried to create a PTR record that is the first in this address space. You must first create at least the following DNS domain: {$octets[$octcount]}{$arpa}", 3); $self['error'] = "ERROR => This operation tried to create a PTR record that is the first in this address space. You must first create at least the following DNS domain: {$octets[$octcount]}{$arpa}. You could also create domains for deeper level reverse zones."; return array(9, $self['error'] . "\n"); } // PTR records dont need a name set. $add_name = ''; // PTR records should not have domain_ids $add_domainid = $ptrdomain['id']; $add_interfaceid = $interface['id']; $add_dnsid = $arecord['id']; // Dont print a dot unless hostname has a value if ($hostname) { $hostname = $hostname . '.'; } $info_msg = "{$ipflip}{$arpa} -> {$hostname}{$domain['fqdn']}"; } else { if ($options['type'] == 'CNAME') { // 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['pointsto']); printmsg("DEBUG => ona_find_domain({$options['pointsto']}) returned: {$domain['fqdn']} for pointsto.", 3); // Now find what the host part of $search is $phostname = str_replace(".{$pdomain['fqdn']}", '', $options['pointsto']); // Validate that the DNS name has only valid characters in it $phostname = sanitize_hostname($phostname); if (!$phostname) { printmsg("ERROR => Invalid pointsto host name ({$options['pointsto']})!", 3); $self['error'] = "ERROR => Invalid pointsto host name ({$options['pointsto']})!"; return array(4, $self['error'] . "\n"); } // Debugging printmsg("DEBUG => Using 'pointsto' hostname: {$phostname}.{$pdomain['fqdn']}, Domain ID: {$pdomain['id']}", 3); // Validate that the CNAME I'm adding doesnt match an existing A record. list($d_status, $d_rows, $d_record) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'type' => 'A', 'dns_view_id' => $add_viewid)); if ($d_status or $d_rows) { printmsg("ERROR => Another DNS A record named {$hostname}.{$domain['fqdn']} already exists!{$viewmsg}", 3); $self['error'] = "ERROR => Another DNS A record named {$hostname}.{$domain['fqdn']} already exists!{$viewmsg}"; return array(5, $self['error'] . "\n"); } // Validate that there are no CNAMES already with this fqdn list($c_status, $c_rows, $c_record) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'type' => 'CNAME', 'dns_view_id' => $add_viewid)); if ($c_rows or $c_status) { printmsg("ERROR => Another DNS CNAME record named {$hostname}.{$domain['fqdn']} already exists!{$viewmsg}", 3); $self['error'] = "ERROR => Another DNS CNAME record named {$hostname}.{$domain['fqdn']} already exists!{$viewmsg}"; return array(5, $self['error'] . "\n"); } // 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' => $add_viewid)); if ($status or !$rows) { printmsg("ERROR => Unable to find DNS A record to point CNAME entry to!{$viewmsg}", 3); $self['error'] = "ERROR => Unable to find DNS A record to point CNAME entry to!{$viewmsg}"; return array(5, $self['error'] . "\n"); } $add_name = $hostname; $add_domainid = $domain['id']; $add_interfaceid = $pointsto_record['interface_id']; $add_dnsid = $pointsto_record['id']; // Dont print a dot unless hostname has a value if ($hostname) { $hostname = $hostname . '.'; } $info_msg = "{$hostname}{$domain['fqdn']} -> {$phostname}.{$pdomain['fqdn']}"; } else { if ($options['type'] == 'NS') { // find the domain list($status, $rows, $domain) = ona_find_domain($options['name'], 0); if (!$domain['id']) { printmsg("ERROR => Invalid domain name ({$options['name']})!", 3); $self['error'] = "ERROR => Invalid domain name ({$options['name']})!"; return array(4, $self['error'] . "\n"); } // 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['pointsto']); printmsg("DEBUG => ona_find_domain({$options['pointsto']}) returned: {$pdomain['fqdn']} for pointsto.", 3); // Now find what the host part of $search is $phostname = str_replace(".{$pdomain['fqdn']}", '', $options['pointsto']); // lets test out if it has a / in it to strip the view name portion // if (strstr($phostname,'/')) { // list($dnsview,$phostname) = explode('/', $phostname); // list($status, $rows, $view) = db_get_record($onadb, 'dns_views', array('name' => strtoupper($dnsview))); // if($rows) $add_pointsto_viewid = $view['id']; // } // Validate that the DNS name has only valid characters in it $phostname = sanitize_hostname($phostname); if (!$phostname) { printmsg("ERROR => Invalid pointsto host name ({$options['pointsto']})!", 3); $self['error'] = "ERROR => Invalid pointsto host name ({$options['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' => $add_pointsto_viewid)); if ($status or !$rows) { printmsg("ERROR => Unable to find DNS A record to point NS entry to!{$viewmsg}", 3); $self['error'] = "ERROR => Unable to find DNS A record to point NS entry to!{$viewmsg}"; return array(5, $self['error'] . "\n"); } // Validate that there are no NS already with this domain and host list($status, $rows, $record) = ona_get_dns_record(array('dns_id' => $pointsto_record['id'], 'domain_id' => $domain['id'], 'type' => 'NS', 'dns_view_id' => $add_viewid)); if ($rows or $status) { printmsg("ERROR => Another DNS NS record for {$domain['fqdn']} pointing to {$options['pointsto']} already exists!{$viewmsg}", 3); $self['error'] = "ERROR => Another DNS NS record for {$domain['fqdn']} pointing to {$options['pointsto']} already exists!{$viewmsg}"; return array(5, $self['error'] . "\n"); } $add_name = ''; //$options['name']; $add_domainid = $domain['id']; $add_interfaceid = $pointsto_record['interface_id']; $add_dnsid = $pointsto_record['id']; $info_msg = "{$options['name']} -> {$phostname}.{$pdomain['fqdn']}"; } else { if ($options['type'] == 'MX') { // If there is no mx_preference set then stop if (!isset($options['mx_preference']) or ($options['mx_preference'] < 0 or $options['mx_preference'] > 65536)) { printmsg("ERROR => You must provide an MX preference value when creating MX records!", 3); $self['error'] = "ERROR => You must provide an MX preference value when creating MX records!"; return array(4, $self['error'] . "\n"); } // Lets try to find the name as a domain first.. if it matches a domain use that, othewise search for an A record $hostname = ''; list($status, $rows, $domain) = ona_get_domain_record(array('name' => $options['name'])); if (!$domain['id']) { // Determine the host and domain name portions of the pointsto option // Find the domain name piece of $search list($status, $rows, $domain) = ona_find_domain($options['name']); printmsg("DEBUG => ona_find_domain({$options['name']}) returned: {$domain['fqdn']}.", 3); // Now find what the host part of $search is $hostname = str_replace(".{$domain['fqdn']}", '', $options['name']); // Validate that the DNS name has only valid characters in it $hostname = sanitize_hostname($hostname); if (!$hostname) { printmsg("ERROR => Invalid host name ({$options['name']})!", 3); $self['error'] = "ERROR => Invalid host name ({$options['name']})!"; return array(4, $self['error'] . "\n"); } // Debugging printmsg("DEBUG => Using hostname: {$hostname}.{$domain['fqdn']}, Domain ID: {$domain['id']}", 3); } // 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['pointsto']); printmsg("DEBUG => ona_find_domain({$options['pointsto']}) returned: {$pdomain['fqdn']} for pointsto.", 3); // Now find what the host part of $search is $phostname = str_replace(".{$pdomain['fqdn']}", '', $options['pointsto']); // Validate that the DNS name has only valid characters in it $phostname = sanitize_hostname($phostname); if (!$phostname) { printmsg("ERROR => Invalid pointsto host name ({$options['pointsto']})!", 3); $self['error'] = "ERROR => Invalid pointsto host name ({$options['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' => $add_viewid)); if ($status or !$rows) { printmsg("ERROR => Unable to find DNS A record to point NS entry to!{$viewmsg}", 3); $self['error'] = "ERROR => Unable to find DNS A record to point NS entry to!{$viewmsg}"; return array(5, $self['error'] . "\n"); } $add_name = $hostname; $add_domainid = $domain['id']; $add_interfaceid = $pointsto_record['interface_id']; $add_dnsid = $pointsto_record['id']; $add_mx_preference = $options['mx_preference']; // Dont print a dot unless hostname has a value if ($hostname) { $hostname = $hostname . '.'; } $info_msg = "{$hostname}{$domain['fqdn']} -> {$phostname}.{$pdomain['fqdn']}"; } else { if ($options['type'] == 'SRV') { // If there is no srv_pri set then stop if (!isset($options['srv_pri']) or ($options['srv_pri'] < 0 or $options['srv_pri'] > 65536)) { printmsg("ERROR => You must provide an SRV priority value between 0-65535 when creating SRV records!", 3); $self['error'] = "ERROR => You must provide an SRV priority value between 0-65535 when creating SRV records!"; return array(4, $self['error'] . "\n"); } // If there is no srv_weight set then stop if (!isset($options['srv_weight']) or ($options['srv_weight'] < 0 or $options['srv_weight'] > 65536)) { printmsg("ERROR => You must provide an SRV weight value between 0-65535 when creating SRV records!", 3); $self['error'] = "ERROR => You must provide an SRV weight value between 0-65535 when creating SRV records!"; return array(4, $self['error'] . "\n"); } // If there is no srv_port set then stop if (!isset($options['srv_port']) or ($options['srv_port'] < 0 or $options['srv_port'] > 65536)) { printmsg("ERROR => You must provide an SRV port value between 0-65535 when creating SRV records!", 3); $self['error'] = "ERROR => You must provide an SRV port value between 0-65535 when creating SRV records!"; return array(4, $self['error'] . "\n"); } // find the domain list($status, $rows, $domain) = ona_find_domain($options['name'], 0); if (!$domain['id']) { printmsg("ERROR => Invalid domain name ({$options['name']})!", 3); $self['error'] = "ERROR => Invalid domain name ({$options['name']})!"; return array(4, $self['error'] . "\n"); } // 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['pointsto']); printmsg("DEBUG => ona_find_domain({$options['pointsto']}) returned: {$pdomain['fqdn']} for pointsto.", 3); // Now find what the host part of $search is $phostname = str_replace(".{$pdomain['fqdn']}", '', $options['pointsto']); // Validate that the DNS name has only valid characters in it $phostname = sanitize_hostname($phostname); if (!$phostname) { printmsg("ERROR => Invalid pointsto host name ({$options['pointsto']})!", 3); $self['error'] = "ERROR => Invalid pointsto host name ({$options['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' => $add_viewid)); if ($status or !$rows) { printmsg("ERROR => Unable to find DNS A record to point SRV entry to!{$viewmsg}", 3); $self['error'] = "ERROR => Unable to find DNS A record to point SRV entry to!{$viewmsg}"; return array(5, $self['error'] . "\n"); } // Validate that there are no records already with this domain and host list($status, $rows, $record) = ona_get_dns_record(array('dns_id' => $pointsto_record['id'], 'name' => $hostname, 'domain_id' => $domain['id'], 'type' => 'SRV', 'dns_view_id' => $add_viewid)); if ($rows or $status) { printmsg("ERROR => Another DNS SRV record for {$hostname}.{$domain['fqdn']} pointing to {$options['pointsto']} already exists!{$viewmsg}", 3); $self['error'] = "ERROR => Another DNS SRV record for {$hostname}.{$domain['fqdn']} pointing to {$options['pointsto']} already exists!{$viewmsg}"; return array(5, $self['error'] . "\n"); } $add_name = $hostname; $add_domainid = $domain['id']; $add_interfaceid = $pointsto_record['interface_id']; $add_dnsid = $pointsto_record['id']; $add_srv_pri = $options['srv_pri']; $add_srv_weight = $options['srv_weight']; $add_srv_port = $options['srv_port']; // Dont print a dot unless hostname has a value if ($hostname) { $hostname = $hostname . '.'; } $info_msg = "{$hostname}{$domain['fqdn']} -> {$phostname}.{$pdomain['fqdn']}"; } else { if ($options['type'] == 'TXT') { // There are 3 types of txt record storage // 1. txt that is associated to another A record. So when that A name gets changed so does this TXT // 2. txt associated to just a domain. I.e. no hostname only a domain_id // 3. txt that is arbitrary and not associated with another A record. has name, domain_id but no dns_id // Set interface id to zero by default, only needed if associating with an IP address $add_interfaceid = 0; // Blank dnsid first.. normally it wont get set, unless it does match up to another record $add_dnsid = ''; // 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 ($hostname != '') { list($status, $rows, $hostint) = ona_get_dns_record(array('name' => $hostname, 'domain_id' => $domain['id'], 'type' => 'A', 'dns_view_id' => $add_viewid)); if ($rows == 1) { $add_interfaceid = $hostint['interface_id']; $add_dnsid = $hostint['id']; } } // If you want to associate a TXT record with a host you need to provide an IP.. otherwise it will just be associated with the domain its in. // I might also check here that if there is no $hostname, then dont use the IP address value even if it is passed if ($options['ip']) { // find the IP interface record, list($status, $rows, $interface) = ona_find_interface($options['ip']); if (!$rows) { printmsg("ERROR => dns_record_add() Unable to find IP interface: {$options['ip']}", 3); $self['error'] = "ERROR => dns_record_add() Unable to find IP interface: {$options['ip']}. TXT records must point to existing IP addresses. Please add an interface with this IP address first."; return array(4, $self['error'] . "\n"); } $add_interfaceid = $interface['id']; } // Validate that there are no TXT already with this domain and host list($status, $rows, $record) = ona_get_dns_record(array('txt' => $options['txt'], 'name' => $hostname, 'domain_id' => $domain['id'], 'type' => 'TXT', 'dns_view_id' => $add_viewid)); if ($rows or $status) { printmsg("ERROR => Another DNS TXT record for {$options['name']} with that text value already exists!{$viewmsg}", 3); $self['error'] = "ERROR => Another DNS TXT record for {$options['name']} with that text value already exists!{$viewmsg}"; return array(5, $self['error'] . "\n"); } $add_name = $hostname; $add_domainid = $domain['id']; $options['txt'] = str_replace('\\=', '=', $options['txt']); $options['txt'] = str_replace('\\&', '&', $options['txt']); $add_txt = $options['txt']; // Dont print a dot unless hostname has a value if ($hostname) { $hostname = $hostname . '.'; } $info_msg = "{$hostname}{$domain['fqdn']}"; } else { printmsg("ERROR => Invalid DNS record type: {$options['type']}!", 3); $self['error'] = "ERROR => Invalid DNS record type: {$options['type']}!"; return array(5, $self['error'] . "\n"); } } } } } } } //FIXME: MP, will this use its own dns_record_add permission? or use host_add? // 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 dns record $id = ona_get_next_id('dns'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id('dns') call failed!"; printmsg($self['error'], 0); return array(7, $self['error'] . "\n"); } printmsg("DEBUG => ID for new dns record: {$id}", 3); // If a ttl was passed use it, otherwise use what was in the domain minimum if ($options['ttl']) { $add_ttl = $options['ttl']; } else { $add_ttl = ''; } // 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 dns record list($status, $rows) = db_insert_record($onadb, 'dns', array('id' => $id, 'domain_id' => $add_domainid, 'interface_id' => $add_interfaceid, 'dns_id' => $add_dnsid, 'type' => $options['type'], 'ttl' => $add_ttl, 'name' => $add_name, 'mx_preference' => $add_mx_preference, 'txt' => $add_txt, 'srv_pri' => $add_srv_pri, 'srv_weight' => $add_srv_weight, 'srv_port' => $add_srv_port, 'ebegin' => $options['ebegin'], 'notes' => $options['notes'], 'dns_view_id' => $add_viewid)); if ($status or !$rows) { $self['error'] = "ERROR => dns_record_add() SQL Query failed adding dns record: " . $self['error']; printmsg($self['error'], 1); return array(6, $self['error'] . "\n"); } $text = ''; // If it is an A record and they have specified to auto add the PTR record for it. if ($options['addptr'] == 'Y' and $options['type'] == 'A') { printmsg("DEBUG => Auto adding a PTR record for {$options['name']}.", 4); // Run dns_record_add as a PTR type list($status, $output) = run_module('dns_record_add', array('name' => $options['name'], 'domain' => $domain['fqdn'], 'ip' => $options['ip'], 'ebegin' => $options['ebegin'], 'type' => 'PTR', 'view' => $add_viewid)); if ($status) { return array($status, $output); printmsg($output, 3); } } // TRIGGER: Since we are adding a new record, lets mark the domain for rebuild on its servers list($status, $rows) = db_update_record($onadb, 'dns_server_domains', array('domain_id' => $add_domainid), 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"); } // Else start an output message $text .= "INFO => DNS {$options['type']} record ADDED: {$info_msg}"; printmsg($text, 0); $text .= "\n"; // Return the success notice return array(0, $text); }
function subnet_add($options = "") { global $conf, $self, $onadb; printmsg('DEBUG => subnet_add(' . $options . ') called', 3); // Version - UPDATE on every edit! $version = '1.06'; // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !($options['ip'] and $options['netmask'] and $options['type'] and $options['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 subnet_add-v{$version} Adds a new subnet (subnet) record Synopsis: subnet_add [KEY=VALUE] ... Required: name=TEXT subnet name (i.e. "LAN-1234") ip=ADDRESS dotted (10.0.0.0), IPv6, or numeric subnet address netmask=MASK dotted (255.0.0.0), CIDR (/8), or numeric netmask type=TYPE subnet type name or id Optional: vlan=VLAN vlan name, number campus=CAMPUS vlan campus name or id to help identify vlan EOM ); } // // Define the fields we're inserting // // This variable will contain the info we'll insert into the DB $SET = array(); // Prepare options[ip] - translate IP address to a number $options['ip'] = $ourip = ip_mangle($options['ip'], 'numeric'); if ($ourip == -1) { $self['error'] = "ERROR => The IP address specified is invalid!"; return array(2, $self['error'] . "\n"); } // Prepare options[netmask] - translate IP address to a number $options['netmask'] = ip_mangle($options['netmask'], 'numeric'); if ($options['netmask'] == -1) { $self['error'] = "ERROR => The netmask specified is invalid!"; return array(3, $self['error'] . "\n"); } // Validate the netmask is okay $cidr = ip_mangle($options['netmask'], 'cidr'); if ($cidr == -1) { $self['error'] = "ERROR => The netmask specified is invalid!"; return array(4, $self['error'] . "\n"); } if (is_ipv4($ourip)) { // echo "ipv4"; $padding = 32; $fmt = 'dotted'; $ip1 = ip_mangle($ourip, 'binary'); $num_hosts = 0xffffffff - $options['netmask']; $last_host = $options['ip'] + $num_hosts; } else { // echo "ipv6"; $padding = 128; $fmt = 'ipv6gz'; $ip1 = ip_mangle($ourip, 'bin128'); $sub = gmp_sub("340282366920938463463374607431768211455", $options['netmask']); $num_hosts = gmp_strval($sub); $last_host = gmp_strval(gmp_add($options['ip'], $num_hosts)); } // Validate that the subnet IP & netmask combo are valid together. $ip2 = str_pad(substr($ip1, 0, $cidr), $padding, '0'); $ip1 = ip_mangle($ip1, $fmt); $ip2 = ip_mangle($ip2, $fmt); if ($ip1 != $ip2) { $self['error'] = "ERROR => Invalid subnet specified - did you mean: {$ip2}/{$cidr}?"; return array(5, $self['error'] . "\n"); } // *** Check to see if the new subnet overlaps any existing ONA subnets *** // // I convert the IP address to dotted format when calling ona_find_subnet() // because it saves it from doing a few unnecessary sql queries. // Look for overlaps like this (where new subnet address starts inside an existing subnet): // [ -- new subnet -- ] // [ -- old subnet --] list($status, $rows, $subnet) = ona_find_subnet(ip_mangle($options['ip'], 'dotted')); if ($rows != 0) { $self['error'] = "ERROR => Subnet address conflict! New subnet starts inside an existing subnet."; return array(6, $self['error'] . "\n" . "ERROR => Conflicting subnet record ID: {$subnet['id']}\n"); } // Look for overlaps like this (where the new subnet ends inside an existing subnet): // [ -- new subnet -- ] // [ -- old subnet --] // Find last address of our subnet, and see if it's inside of any other subnet: list($status, $rows, $subnet) = ona_find_subnet(ip_mangle($last_host, 'dotted')); if ($rows != 0) { $self['error'] = "ERROR => Subnet address conflict! New subnet ends inside an existing subnet."; return array(7, $self['error'] . "\n" . "ERROR => Conflicting subnet record ID: {$subnet['id']}\n"); } // Look for overlaps like this (where the new subnet entirely overlaps an existing subnet): // [ -------- new subnet --------- ] // [ -- old subnet --] // // Do a cool SQL query to find any subnets whoose start address is >= or <= the // new subnet base address. $where = "ip_addr >= {$options['ip']} AND ip_addr <= {$last_host}"; list($status, $rows, $subnet) = ona_get_subnet_record($where); if ($rows != 0) { $self['error'] = "ERROR => Subnet address conflict! New subnet would encompass an existing subnet."; return array(8, $self['error'] . "\n" . "ERROR => Conflicting subnet record ID: {$subnet['id']}\n"); } // The IP/NETMASK look good, set them. $SET['ip_addr'] = $options['ip']; $SET['ip_mask'] = $options['netmask']; // Find the type from $options[type] list($status, $rows, $subnet_type) = ona_find_subnet_type($options['type']); if ($status or $rows != 1) { $self['error'] = "ERROR => Invalid subnet type specified!"; return array(10, $self['error'] . "\n"); } printmsg("Subnet type selected: {$subnet_type['name']} ({$subnet_type['short_name']})", 1); $SET['subnet_type_id'] = $subnet_type['id']; // Find the VLAN ID from $options[vlan] and $options[campus] if ($options['vlan'] or $options['campus']) { list($status, $rows, $vlan) = ona_find_vlan($options['vlan'], $options['campus']); if ($status or $rows != 1) { $self['error'] = "ERROR => The vlan/campus pair specified is invalid!"; return array(11, $self['error'] . "\n"); } printmsg("VLAN selected: {$vlan['name']} in {$vlan['vlan_campus_name']} campus", 1); $SET['vlan_id'] = $vlan['id']; } // Sanitize "name" option // We require subnet names to be in upper case and spaces are converted to -'s. $options['name'] = trim($options['name']); $options['name'] = preg_replace('/\\s+/', '-', $options['name']); $options['name'] = strtoupper($options['name']); // Make sure there's not another subnet with this name list($status, $rows, $tmp) = ona_get_subnet_record(array('name' => $options['name'])); if ($status or $rows) { $self['error'] = "ERROR => That name is already used by another subnet!"; return array(12, $self['error'] . "\n"); } $SET['name'] = $options['name']; // Check permissions if (!auth('subnet_add')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(14, $self['error'] . "\n"); } // Get the next ID for the new interface $id = ona_get_next_id('subnets'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; return array(15, $self['error'] . "\n"); } printmsg("DEBUG => ID for new subnet: " . $id, 1); $SET['id'] = $id; // Insert the new subnet record list($status, $rows) = db_insert_record($onadb, 'subnets', $SET); // Report errors if ($status or !$rows) { return array(16, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => Subnet ADDED: {$ip1}/{$cidr}"; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
function dhcp_entry_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.03'; printmsg("DEBUG => dhcp_entry_add({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // if global is set to N then get rid of it entirely from the options array $options['global'] = sanitize_YN($options['global'], 'N'); if ($options['global'] == 'N') { unset($options['global']); } // Return the usage summary if we need to if ($options['help'] or !($options['option'] and array_key_exists('value', $options) and ($options['server'] and !($options['host'] or $options['subnet'] or $options['global']) or $options['host'] and !($options['server'] or $options['subnet'] or $options['global']) or $options['subnet'] and !($options['host'] or $options['server'] or $options['global']) or array_key_exists('global', $options) and !($options['host'] or $options['server'] or $options['subnet'])))) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dhcp_entry_add-v{$version} Adds a dhcp entry into the database pointing to the specified identifier Synopsis: dhcp_entry_add [KEY=VALUE] ... Identifier (pick one): host=HOSTNAME[.DOMAIN] or ID host identifier to add to subnet=NAME or ID subnet identifier to add to server=NAME[.DOMAIN] or ID server identifier to add to global global entry for all subnets/hosts etc Options (both required): option=DHCP option name DHCP option name (as identified in ONA) value=STRING string value for the DHCP type EOM ); } // trim leading and trailing whitespace from 'value' and check that a value exists $dhcp_option_value = trim($options['value']); if (strlen($dhcp_option_value) == 0) { printmsg("DEBUG => The DHCP value was blank", 3); $self['error'] = "ERROR => DHCP value was blank"; return array(2, $self['error'] . "\n"); } if ($options['global'] == 'Y') { $anchor = 'global'; $desc = 'Global DHCP option'; $lvl = 0; $subnet['id'] = 0; $server['host_id'] = 0; $host['id'] = 0; } elseif ($options['host']) { // Determine the host is valid list($status, $rows, $host) = ona_find_host($options['host']); if (!$host['id']) { printmsg("DEBUG => The host specified, {$options['host']}, does not exist!", 3); $self['error'] = "ERROR => The host specified, {$options['host']}, does not exist!"; return array(2, $self['error'] . "\n"); } $anchor = 'host'; $desc = $host['fqdn']; $lvl = $host['lvl']; $subnet['id'] = 0; $server['host_id'] = 0; } elseif ($options['subnet']) { // Determine the subnet is valid list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); if (!$subnet['id']) { printmsg("DEBUG => The subnet specified, {$options['subnet']}, does not exist!", 3); $self['error'] = "ERROR => The subnet specified, {$options['subnet']}, does not exist!"; return array(3, $self['error'] . "\n"); } $anchor = 'subnet'; $desc = "{$subnet['name']} (" . ip_mangle($subnet['ip_addr']) . ")"; $lvl = $subnet['lvl']; $host['id'] = 0; $server['host_id'] = 0; } elseif ($options['server']) { // Determine the server is valid list($status, $rows, $host) = ona_find_host($options['server']); if (!$host['id']) { printmsg("DEBUG => The server specified, {$options['server']}, does not exist!", 3); $self['error'] = "ERROR => The server specified, {$options['server']}, does not exist!"; return array(4, $self['error'] . "\n"); } // Determine the host that was found is actually a server list($status, $rows, $server) = ona_get_dhcp_server_subnet_record(array('host_id' => $host['id'])); if (!$rows) { printmsg("DEBUG => The host specified, {$host['fqdn']}, is not a DHCP server!", 3); $self['error'] = "ERROR => The host specified, {$host['fqdn']}, is not a DHCP server!"; return array(5, $self['error'] . "\n"); } $anchor = 'server'; $desc = $host['fqdn']; $lvl = $host['lvl']; $host['id'] = 0; $subnet['id'] = 0; } // Determine the type is valid list($status, $rows, $type) = ona_find_dhcp_option($options['option']); if (!$type['id']) { printmsg("DEBUG => The DHCP parameter type specified, {$options['option']}, does not exist!", 3); $self['error'] = "ERROR => The DHCP parameter type specified, {$options['option']}, does not exist!"; return array(8, $self['error'] . "\n"); } printmsg("DEBUG => dhcp_entry_add(): Found DHCP option {$type['display_name']}", 3); // Make sure this isn't a duplicate $search = array('dhcp_option_id' => $type['id'], 'host_id' => 0, 'subnet_id' => 0); if ($host['id']) { $search['host_id'] = $host['id']; } if ($subnet['id']) { $search['subnet_id'] = $subnet['id']; } if ($server['id']) { $search['server_id'] = $server['id']; } list($status, $rows, $record) = ona_get_dhcp_option_entry_record($search); if ($status or $rows) { printmsg("DEBUG => That DHCP option, {$type['display_name']}, is already defined!", 3); $self['error'] = "ERROR => That DHCP option ({$type['display_name']}) is already defined!"; return array(11, $self['error'] . "\n"); } // Check permissions if (!auth('advanced') or !authlvl($lvl)) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // Get the next id $id = ona_get_next_id('dhcp_option_entries'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } printmsg("DEBUG => dhcp_entry_add(): New ID: {$id}", 3); // Add the record list($status, $rows) = db_insert_record($onadb, 'dhcp_option_entries', array('id' => $id, 'dhcp_option_id' => $type['id'], 'value' => $dhcp_option_value, 'host_id' => $host['id'], 'server_id' => $server['host_id'], 'subnet_id' => $subnet['id'])); if ($status or !$rows) { $self['error'] = "ERROR => dhcp_entry_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(7, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => DHCP entry ADDED: {$type['display_name']}={$dhcp_option_value} on {$desc} "; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
function dhcp_failover_group_add($options = "") { global $conf, $self, $onadb; printmsg("DEBUG => dhcp_failover_group_add({$options}) called", 3); // Version - UPDATE on every edit! $version = '1.00'; // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !($options['pri_server'] and $options['sec_server'] or ($options['response_delay'] or $options['unacked_updates'] or $options['max_balance'] or $options['priport'] or $options['peerport'] or $options['mclt'] or $options['split']))) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dhcp_failover_group_add-v{$version} Adds a DHCP failover group into the database Synopsis: dhcp_failover_group_add [KEY=VALUE] ... Required: pri_server=NAME[.DOMAIN] or ID identifier of the primary server sec_server=NAME[.DOMAIN] or ID identifier of the secondary server Optional: response_delay=NUMBER Default ({$conf['dhcp_response_delay']}) unacked_updates=NUMBER Default ({$conf['dhcp_unacked_updates']}) max_balance=NUMBER Default ({$conf['dhcp_max_balance']}) priport=NUMBER Default ({$conf['dhcp_priport']}) peerport=NUMBER Default ({$conf['dhcp_peerport']}) mclt=NUMBER Default ({$conf['dhcp_mclt']}) split=NUMBER Default ({$conf['dhcp_split']}) EOM ); } if ($options['pri_server']) { // Determine the server is valid list($status, $rows, $pri_server) = ona_find_host($options['pri_server']); if (!$pri_server['id']) { printmsg("DEBUG => The server specified, {$options['pri_server']}, does not exist!", 3); $self['error'] = "ERROR => The server specified, {$options['pri_server']}, does not exist!"; return array(2, $self['error'] . "\n"); } // Determine the host that was found is actually a server // MP: FIXME: dont think I'm going to pursue doing a seperate server table.. lets remove /* list($status, $rows, $pri_server) = ona_get_server_record(array('host_id' => $pri_host['id'])); if (!$pri_server['id']) { printmsg("DEBUG => The host specified, {$pri_host['fqdn']}, is not a server!",3); $self['error'] = "ERROR => The host specified, {$pri_host['fqdn']}, is not a server!"; return(array(5, $self['error'] . "\n")); }*/ } if ($options['sec_server']) { // Determine the server is valid list($status, $rows, $sec_server) = ona_find_host($options['sec_server']); if (!$sec_server['id']) { printmsg("DEBUG => The server specified, {$options['sec_server']}, does not exist!", 3); $self['error'] = "ERROR => The server specified, {$options['sec_server']}, does not exist!"; return array(2, $self['error'] . "\n"); } // Determine the host that was found is actually a server // MP: FIXME: dont think I'm going to pursue doing a seperate server table.. lets remove /* list($status, $rows, $sec_server) = ona_get_server_record(array('HOST_id' => $sec_host['id'])); if (!$sec_server['id']) { printmsg("DEBUG => The host specified, {$sec_host['fqdn']}, is not a server!",3); $self['error'] = "ERROR => The host specified, {$sec_host['fqdn']}, is not a server!"; return(array(5, $self['error'] . "\n")); }*/ } // The pri/sec server can not be the same if ($pri_server['id'] == $sec_server['id']) { printmsg("DEBUG => The primary server and the secondary server cannot be the same ({$pri_host['fqdn']}).", 3); $self['error'] = "ERROR => The primary server and the secondary server cannot be the same ({$pri_host['fqdn']})."; return array(9, $self['error'] . "\n"); } // Validate that this failover group doesnt already exist list($status, $rows, $record) = ona_get_dhcp_failover_group_record(array('primary_server_id' => $pri_server['id'], 'secondary_server_id' => $sec_server['id'])); // Check the reverse primary/secondary host pairing.. if (!$rows) { list($status, $rows, $record) = ona_get_dhcp_failover_group_record(array('primary_server_id' => $sec_server['id'], 'secondary_server_id' => $pri_server['id'])); } if ($rows) { printmsg("DEBUG => A failover group using, {$options['pri_server']} and {$options['sec_server']}, already exists!", 3); $self['error'] = "ERROR => A failover group using, {$options['pri_server']} and {$options['sec_server']}, already exists!"; return array(11, $self['error'] . "\n"); } // Use default if something was not passed on command line if ($options['response_delay']) { $response_delay = $options['response_delay']; } else { $response_delay = $conf['dhcp_response_delay']; } if ($options['unacked_updates']) { $unacked_updates = $options['unacked_updates']; } else { $unacked_updates = $conf['dhcp_unacked_updates']; } if ($options['max_balance']) { $max_balance = $options['max_balance']; } else { $max_balance = $conf['dhcp_max_balance']; } if ($options['priport']) { $priport = $options['priport']; } else { $priport = $conf['dhcp_priport']; } if ($options['peerport']) { $peerport = $options['peerport']; } else { $peerport = $conf['dhcp_peerport']; } if ($options['mclt']) { $mclt = $options['mclt']; } else { $mclt = $conf['dhcp_mclt']; } if ($options['split']) { $split = $options['split']; } else { $split = $conf['dhcp_split']; } // 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('dhcp_failover_groups'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } printmsg("DEBUG => dhcp_failover_group_add(): New failover group id: {$id}", 3); // Add the record list($status, $rows) = db_insert_record($onadb, 'dhcp_failover_groups', array('id' => $id, 'primary_server_id' => $pri_server['id'], 'secondary_server_id' => $sec_server['id'], 'max_response_delay' => $response_delay, 'max_unacked_updates' => $unacked_updates, 'max_load_balance' => $max_balance, 'primary_port' => $priport, 'peer_port' => $peerport, 'mclt' => $mclt, 'split' => $split)); if ($status or !$rows) { $self['error'] = "ERROR => dhcp_failover_group_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(7, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => DHCP failover group ADDED: {$id} => PRI:{$pri_host['fqdn']} SEC:{$sec_host['fqdn']}"; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
function ws_save($window_name, $form = '') { global $conf, $self, $onadb; // Check permissions if (!auth('advanced')) { $response = new xajaxResponse(); $response->addScript("alert('Permission denied!');"); return $response->getXML(); } // Instantiate the xajaxResponse object $response = new xajaxResponse(); $js = ''; // Validate Input if ($form['short_name'] == '' or $form['display_name'] == '') { $response->addScript("alert('Please complete all fields to continue!');"); return $response->getXML(); } // BUSINESS RULE: Force short_name to be console friendly (a-z,-, & _ only) $form['short_name'] = strtolower($form['short_name']); if (!preg_match('/^[\\w-_]+$/', $form['short_name'])) { $response->addScript("alert('Invalid short name! Please use only script-friendly characters: a-z - _ (no spaces)');"); return $response->getXML(); } // If you get a numeric in $form, update the record if (is_numeric($form['id'])) { list($status, $rows) = db_update_record($onadb, 'subnet_types', array('id' => $form['id']), array('short_name' => $form['short_name'], 'display_name' => $form['display_name'], 'notes' => $form['notes'])); } else { $id = ona_get_next_id('subnet_types'); list($status, $rows) = db_insert_record($onadb, 'subnet_types', array('id' => $id, 'display_name' => $form['display_name'], 'short_name' => $form['short_name'], 'notes' => $form['notes'])); } // If the module returned an error code display a popup warning if ($status) { $js .= "alert('Save failed. " . trim($self['error']) . " (Hint: All fields are required!)');"; } else { $js .= "removeElement('{$window_name}');"; $js .= "xajax_window_submit('app_subnet_type_list', xajax.getFormValues('app_subnet_type_list_filter_form'), 'display_list');"; } // Return some javascript to the browser $response->addScript($js); return $response->getXML(); }
function vlan_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.01'; printmsg("DEBUG => vlan_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['campus'] and $options['name'] and $options['number'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM vlan_add-v{$version} Adds a vlan into the database assigned to the specified campus Synopsis: vlan_add [KEY=VALUE] ... Required: campus=STRING|ID Campus name or row ID name=STRING Name of new VLAN number=NUMBER VLAN number to be assigned EOM ); } // The formatting rule on vlan names/campus names is all upper and trim it, spaces to - $options['name'] = strtoupper(trim($options['name'])); $options['name'] = preg_replace('/\\s+/', '-', $options['name']); $options['campus'] = strtoupper(trim($options['campus'])); $options['number'] = trim($options['number']); if (is_numeric($options['campus'])) { list($status, $rows, $campus) = ona_get_vlan_campus_record(array('id' => $options['campus'])); } if (!$rows) { list($status, $rows, $campus) = ona_get_vlan_campus_record(array('name' => $options['campus'])); } if ($status or !$rows) { $self['error'] = "ERROR => Unable to find campus"; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } // Debugging printmsg("DEBUG => Using VLAN campus: {$campus['name']}", 3); // check that the number option is a number if (!is_numeric($options['number'])) { printmsg("DEBUG => The VLAN number ({$options['number']}) must be numeric!", 3); $self['error'] = "ERROR => The VLAN number ({$options['number']}) must be numeric!"; return array(3, $self['error'] . "\n"); } // Validate that there isn't already an vlan on this campus with this vlan number list($status, $rows, $record) = ona_get_vlan_record(array('vlan_campus_id' => $campus['id'], 'number' => $options['number'])); if ($status or $rows) { printmsg("DEBUG => The vlan campus ({$campus['name']}) already has a vlan with the number ({$options['number']})!", 3); $self['error'] = "ERROR => The vlan campus {$campus['name']} already has a vlan with the number {$options['number']}!"; return array(3, $self['error'] . "\n"); } // Validate that there isn't already an vlan list($v_status, $v_rows, $v_record) = ona_get_vlan_record(array('vlan_campus_id' => $campus['id'], 'name' => $options['name'])); if ($v_status or $v_rows) { printmsg("DEBUG => The vlan ({$options['name']}) already exists on campus ({$campus['name']})!", 3); $self['error'] = "ERROR => The vlan {$options['name']} already exists on campus {$campus['name']}!"; return array(3, $self['error'] . "\n"); } // Check permissions if (!auth('vlan_add')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // Get the next ID for the new vlan $id = ona_get_next_id('vlans'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } printmsg("DEBUG => ID for new VLAN: {$id}", 3); // Add the vlan list($status, $rows) = db_insert_record($onadb, 'vlans', array('id' => $id, 'number' => $options['number'], 'name' => $options['name'], 'vlan_campus_id' => $campus['id'])); if ($status or !$rows) { $self['error'] = "ERROR => vlan_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => VLAN ADDED: {$options['name']} to {$campus['name']}."; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
function location_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.01'; printmsg("DEBUG => location_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['reference'] and $options['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 location_add-v{$version} Adds a location into the database Synopsis: location_add [KEY=VALUE] ... Required: reference=STRING reference for identifying and searching for location name=STRING location descriptive name Optional: address=STRING city=STRING state=STRING zip_code=NUMBER latitude=STRING longitude=STRING misc=STRING EOM ); } // The formatting rule on location reference is all upper and trim it $options['reference'] = strtoupper(trim($options['reference'])); // check to see if the campus already exists list($status, $rows, $loc) = ona_get_location_record(array('reference' => $options['reference'])); if ($status or $rows) { printmsg("DEBUG => The location {$options['reference']} already exists!", 3); $self['error'] = "ERROR => The location {$options['reference']} already exists!"; return array(3, $self['error'] . "\n"); } // Check permissions if (!auth('location_add')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // Get the next ID for the new location $id = ona_get_next_id('locations'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } printmsg("DEBUG => ID for new location: {$id}", 3); // Add the record list($status, $rows) = db_insert_record($onadb, 'locations', array('id' => $id, 'reference' => $options['reference'], 'name' => $options['name'], 'address' => $options['address'], 'city' => $options['city'], 'state' => $options['state'], 'zip_code' => $options['zip_code'], 'latitude' => $options['latitude'], 'longitude' => $options['longitude'], 'misc' => $options['misc'])); if ($status or !$rows) { $self['error'] = "ERROR => location_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => Location ADDED: {$options['reference']}: {$options['name']}"; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
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"); }
function domain_server_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.02'; printmsg("DEBUG => domain_server_add({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !($options['domain'] and $options['server'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM domain_server_add-v{$version} Assigns an existing domain record to a DNS server Synopsis: domain_server_add [KEY=VALUE] ... Required: domain=NAME or ID domain name or ID server=NAME[.DOMAIN] or ID server name or ID role=master|slave|forward role of this server for this domain EOM ); } // if (is_numeric($options['domain'])) { // $domainsearch['id'] = $options['domain']; // } else { // $domainsearch['name'] = strtolower($options['domain']); // } // Determine the entry itself exists list($status, $rows, $domain) = ona_find_domain($options['domain'], 0); // Test to see that we were able to find the specified record if (!$domain['id']) { printmsg("DEBUG => Unable to find the domain record using {$options['domain']}!", 3); $self['error'] = "ERROR => Unable to find the domain record using {$options['domain']}!"; return array(4, $self['error'] . "\n"); } printmsg("DEBUG => domain_server_add(): Found domain, {$domain['name']}", 3); // Determine the server is valid list($status, $rows, $ns_dns) = ona_find_dns_record($options['server']); list($status, $rows, $interface) = ona_find_interface($ns_dns['interface_id']); $host['id'] = $interface['host_id']; if (!$host['id']) { printmsg("DEBUG => The server ({$options['server']}) does not exist!", 3); $self['error'] = "ERROR => The server specified, {$options['server']}, does not exist!"; return array(2, $self['error'] . "\n"); } // what is the role for this server. switch (strtolower($options['role'])) { case "forward": $role = "forward"; break; case "master": $role = "master"; break; case "slave": $role = "slave"; break; default: $role = "master"; } // Check permissions if (!auth('advanced')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(12, $self['error'] . "\n"); } // Test that this domain isnt already assigned to the server list($status, $rows, $domainserver) = ona_get_dns_server_domain_record(array('host_id' => $host['id'], 'domain_id' => $domain['id'])); if ($rows) { printmsg("DEBUG => Domain {$domain['name']} already assigned to {$options['server']}", 3); $self['error'] = "ERROR => Domain {$domain['name']} already assigned to {$options['server']}"; return array(11, $self['error'] . "\n"); } // Get the next ID $id = ona_get_next_id('dns_server_domains'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); return array(6, $add_to_error . $self['error'] . "\n"); } printmsg("DEBUG => domain_server_add(): New DNS server domain ID: {$id}", 3); // Add new record to dns_server_domains list($status, $rows) = db_insert_record($onadb, 'dns_server_domains', array('id' => $id, 'host_id' => $host['id'], 'domain_id' => $domain['id'], 'role' => $role, 'rebuild_flag' => 1)); if ($status or !$rows) { $self['error'] = "ERROR => domain_server_add() SQL Query failed:" . $self['error']; printmsg($self['error'], 0); return array(8, $add_to_error . $self['error'] . "\n"); } // Test that there are no NS records for this pair already // ASSUMPTION: MP this will always be just one record?? list($status, $dnsrows, $dnsrec) = db_get_record($onadb, 'dns', "domain_id = {$domain['id']} AND type = 'NS' AND interface_id in (select id from interfaces where host_id = {$host['id']})"); // Auto add the NS record if there were none found already. the user can remove any NS records they dont want afterwards if (!$dnsrows) { printmsg("DEBUG => Auto adding a NS record for {$options['server']}.", 0); // Run dns_record_add as a NS type list($status, $output) = run_module('dns_record_add', array('name' => $domain['fqdn'], 'pointsto' => $options['server'], 'type' => 'NS')); if ($status) { return array($status, $output); } $add_to_error .= $output; } else { printmsg("DEBUG => Found existing NS record for {$options['server']}. Skipping the auto add.", 0); } // Return the success notice $self['error'] = "INFO => DNS Domain/Server Pair ADDED: {$domain['name']}/{$options['server']} "; printmsg($self['error'], 0); return array(0, $add_to_error . $self['error'] . "\n"); }
function dhcp_pool_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.03'; printmsg("DEBUG => dhcp_pool_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['start'] and $options['end'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dhcp_pool_add-v{$version} Adds a dhcp pool into the database pointing to the specified identifier Synopsis: dhcp_pool_add [KEY=VALUE] ... Identifier (pick one): failover_group=ID group identifier to add to Required: start=IP IP address for start of pool range end=IP IP address for end of pool range Optional: llength=NUMBER Length in seconds for leases ({$conf['dhcp_pool']['llength']}) EOM ); } // set the lease time if it was passed. otherwise, use the default $llength = $options['llength'] ? $options['llength'] : $conf['dhcp_pool']['llength']; // make it blank for now. $failovergroupid = 0; // make sure that the start address is actually part of an existing subnet list($status, $rows, $subnet) = ona_find_subnet(ip_mangle($options['start'], 'dotted')); if (!$rows) { printmsg("DEBUG => Unable to find a subnet related to starting address ({$options['start']}).", 3); $self['error'] = "ERROR => Unable to find a subnet related to starting address ({$options['start']})."; return array(1, $self['error'] . "\n"); } if ($options['failover_group']) { list($status, $rows, $fg) = ona_get_dhcp_failover_group_record(array('id' => $options['failover_group'])); if (!$fg['id']) { printmsg("DEBUG => The failover_group ({$options['failover_group']}) does not exist!", 3); $self['error'] = "ERROR => The failover_group ({$options['failover_group']}) does not exist!"; return array(4, $self['error'] . "\n"); } // get the server names for the two servers list($fail_host1, $fail_zone1) = ona_find_host($fg['primary_server_id']); list($fail_host2, $fail_zone2) = ona_find_host($fg['secondary_server_id']); $desc = $fail_host1['fqdn'] . '/' . $fail_host2['fqdn']; $serverid = ''; $failovergroupid = $fg['id']; } // check that start and end are not the same //if ($options['start'] == $options['end']) { // printmsg("DEBUG => The start and end IP addresses ({$options['start']}) cannot be the same!",3); // $self['error'] = "ERROR => The start and end IP addresses ({$options['start']}) cannot be the same!"; // return(array(2, $self['error'] . "\n")); //} $start_dec = ip_mangle($options['start'], 'numeric'); $end_dec = ip_mangle($options['end'], 'numeric'); $net_end = 4294967295 - $subnet['ip_mask'] + $subnet['ip_addr']; // Validate that the IP address supplied isn't the base or broadcast of the subnet if ($start_dec == $subnet['ip_addr'] or $end_dec == $subnet['ip_addr']) { printmsg("DEBUG => IP address can't be a subnet's base address (" . ip_mangle($subnet['ip_addr'], 'dotted') . ")!", 3); $self['error'] = "ERROR => IP address can't be a subnet's base address(" . ip_mangle($subnet['ip_addr'], 'dotted') . ")!"; return array(7, $self['error'] . "\n"); } if ($start_dec == $net_end or $end_dec == $net_end) { printmsg("DEBUG => IP address can't be a subnet's broadcast address (" . ip_mangle($net_end, 'dotted') . ")!", 3); $self['error'] = "ERROR => IP address can't be the subnet broadcast address (" . ip_mangle($net_end, 'dotted') . ")!"; return array(8, $self['error'] . "\n"); } // check that start is not after the end if ($start_dec > $end_dec) { printmsg("ERROR => The start IP address ({$options['start']}) falls after the end IP address ({$options['end']})!", 3); $self['error'] = "ERROR => The start IP addresses ({$options['start']}) falls after the end IP address ({$options['end']})!"; return array(2, $self['error'] . "\n"); } // check for existing hosts inside the pool range list($status, $rows, $interface) = db_get_records($onadb, 'interfaces', 'subnet_id = ' . $subnet['id'] . ' AND ip_addr BETWEEN ' . $start_dec . ' AND ' . $end_dec, '', 0); if ($rows) { printmsg("DEBUG => IP conflict: Specified range ({$options['start']}-{$options['end']}) encompasses {$rows} host(s).", 3); $self['error'] = "ERROR => IP conflict: Specified range ({$options['start']}-{$options['end']}) encompasses {$rows} host(s)"; return array(4, $self['error'] . "\n"); } // *** Check to see if the new pool overlaps any existing pools *** // // Look for overlaps like this (where new pool address starts inside an existing pool): // [ -- new pool -- ] // [ -- old pool --] list($status, $rows, $pool) = db_get_record($onadb, 'dhcp_pools', $start_dec . ' BETWEEN ip_addr_start AND ip_addr_end'); if ($rows != 0) { printmsg("DEBUG => Pool address conflict! New pool ({$options['start']}-{$options['end']}) starts inside an existing pool.", 3); $self['error'] = "ERROR => Pool address conflict! New pool ({$options['start']}-{$options['end']}) starts inside an existing pool."; return array(5, $self['error'] . "\n" . "INFO => Conflicting pool record ID: {$pool['id']}\n"); } // Look for overlaps like this (where the new pool ends inside an existing pool): // [ -- new pool -- ] // [ -- old pool --] list($status, $rows, $pool) = db_get_record($onadb, 'dhcp_pools', $end_dec . ' BETWEEN ip_addr_start AND ip_addr_end'); if ($rows != 0) { printmsg("DEBUG => Pool address conflict! New pool ({$options['start']}-{$options['end']}) ends inside an existing pool.", 3); $self['error'] = "ERROR => Pool address conflict! New pool ({$options['start']}-{$options['end']}) ends inside an existing pool."; return array(6, $self['error'] . "\n" . "INFO => Conflicting pool record ID: {$pool['id']}\n"); } // Look for overlaps like this (where the new pool entirely overlaps an existing pool): // [ -------- new pool --------- ] // [ -- old pool --] list($status, $rows, $pool) = db_get_record($onadb, 'dhcp_pools', 'ip_addr_start BETWEEN ' . $start_dec . ' AND ' . $end_dec . ' OR ip_addr_end BETWEEN ' . $start_dec . ' AND ' . $end_dec); if ($rows != 0) { printmsg("DEBUG => Pool address conflict! New pool ({$options['start']}-{$options['end']}) would encompass an existing pool.", 3); $self['error'] = "ERROR => Pool address conflict! New pool ({$options['start']}-{$options['end']}) would encompass an existing pool."; return array(7, $self['error'] . "\n" . "INFO => Conflicting pool record ID: {$pool['id']}\n"); } // Check permissions if (!auth('advanced') or !authlvl($subnet['lvl'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(8, $self['error'] . "\n"); } // Get the next id $id = ona_get_next_id('dhcp_pools'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); return array(9, $add_to_error . $self['error'] . "\n"); } printmsg("DEBUG => dhcp_pool_add(): New ID: {$id}", 3); // Add the record list($status, $rows) = db_insert_record($onadb, 'dhcp_pools', array('id' => $id, 'subnet_id' => $subnet['id'], 'dhcp_failover_group_id' => $failovergroupid, 'ip_addr_start' => $start_dec, 'ip_addr_end' => $end_dec, 'lease_length' => $llength, 'lease_grace_period' => $conf['dhcp_pool']['lgrace'], 'lease_renewal_time' => $conf['dhcp_pool']['lrenewal'], 'lease_rebind_time' => $conf['dhcp_pool']['lrebind'], 'allow_bootp_clients' => $conf['dhcp_pool']['allow_bootp'])); if ($status or !$rows) { $self['error'] = "ERROR => dhcp_pool_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(10, $add_to_error . $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => DHCP pool ADDED: {$options['start']}->{$options['end']}."; printmsg($self['error'], 0); return array(0, $add_to_error . $self['error'] . "\n"); }
function vlan_campus_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.01'; printmsg("DEBUG => vlan_campus_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['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 vlan_campus_add-v{$version} Adds a vlan campus into the database Synopsis: vlan_campus_add [KEY=VALUE] ... Required: name=STRING Campus name EOM ); } // The formatting rule on vlan campus names is all upper and trim it, spaces to - $options['name'] = strtoupper(trim($options['name'])); $options['name'] = preg_replace('/\\s+/', '-', $options['name']); // check to see if the campus already exists list($status, $rows, $campus) = ona_get_vlan_campus_record(array('name' => $options['name'])); if ($status or $rows) { printmsg("DEBUG => The vlan campus {$options['name']} already exists!", 3); $self['error'] = "ERROR => The vlan campus {$options['name']} already exists!"; return array(3, $self['error'] . "\n"); } // Check permissions if (!auth('vlan_add')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // Get the next ID for the new alias $id = ona_get_next_id('vlan_campuses'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } printmsg("DEBUG => ID for new VLAN Campus: {$id}", 3); // Add the record list($status, $rows) = db_insert_record($onadb, 'vlan_campuses', array('id' => $id, 'name' => $options['name'])); if ($status or !$rows) { $self['error'] = "ERROR => vlan_campus_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => VLAN Campus ADDED: {$options['name']}"; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
function ws_save($window_name, $form = '') { global $conf, $self, $onadb; // Check permissions if (!auth('advanced')) { $response = new xajaxResponse(); $response->addScript("alert('Permission denied!');"); return $response->getXML(); } // Instantiate the xajaxResponse object $response = new xajaxResponse(); $js = ''; // Strip whitespace // FIXME: (PK) What about SQL injection attacks? This is a user-entered string... // Sanitize "name" option // We require view names to be in upper case and spaces are converted to -'s. $form['dns_view_name'] = strtoupper(trim($form['dns_view_name'])); $form['dns_view_name'] = preg_replace('/\\s+/', '-', $form['dns_view_name']); $form['dns_view_description'] = trim($form['dns_view_description']); // Don't insert a string of all white space! if (trim($form['dns_view_name']) == "") { $self['error'] = "ERROR => Blank names not allowed."; printmsg($self['error'], 1); $response->addScript("alert('{$self['error']}');"); return $response->getXML(); } // If you get a numeric in $form, update the record if (is_numeric($form['id'])) { // Get the record before updating (logging) list($status, $rows, $original_type) = ona_get_record(array('id' => $form['id']), 'dns_views'); $SET = array(); if (strtoupper($form['dns_view_name']) != $original_type['name']) { // check for an existing entry like this list($status, $rows, $test) = ona_get_record(array('name' => $form['dns_view_name']), 'dns_views'); if ($rows) { $self['error'] = "ERROR => The name you are trying to use already exists."; printmsg($self['error'], 1); $response->addScript("alert('{$self['error']}');"); return $response->getXML(); } $SET['name'] = strtoupper($form['dns_view_name']); } if ($form['dns_view_description'] != $original_type['description']) { $SET['description'] = $form['dns_view_description']; } list($status, $rows) = db_update_record($onadb, 'dns_views', array('id' => $form['id']), $SET); if ($status or !$rows) { $self['error'] = "ERROR => dns_view_edit update ws_save() failed: " . $self['error']; printmsg($self['error'], 1); $response->addScript("alert('{$self['error']}');"); } else { // Get the record after updating (logging) list($status, $rows, $new_type) = ona_get_record(array('id' => $form['id']), 'dns_views'); // Return the success notice $self['error'] = "INFO => DNS view UPDATED:{$new_type['id']}: {$new_type['name']}"; printmsg($self['error'], 0); $log_msg = "INFO => DNS view UPDATED:{$new_type['id']}: name[{$original_type['name']}=>{$new_type['name']}]"; printmsg($log_msg, 0); } } else { // check for an existing entry like this list($status, $rows, $test) = ona_get_record(array('name' => $form['dns_view_name']), 'dns_views'); if ($rows) { $self['error'] = "ERROR => The name you are trying to use already exists."; printmsg($self['error'], 1); $response->addScript("alert('{$self['error']}');"); return $response->getXML(); } $id = ona_get_next_id('dns_views'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 1); } else { printmsg("DEBUG => id for new dns view record: {$id}", 3); list($status, $rows) = db_insert_record($onadb, "dns_views", array('id' => $id, 'name' => strtoupper(trim($form['dns_view_name'])), 'description' => $form['dns_view_description'])); if ($status or !$rows) { $self['error'] = "ERROR => dns_view_edit add ws_save() failed: " . $self['error']; printmsg($self['error'], 1); } else { $self['error'] = "INFO => DNS view ADDED: {$form['dns_view_name']} "; printmsg($self['error'], 0); } } } // If the module returned an error code display a popup warning if ($status or !$rows) { $js .= "alert(\"Save failed. " . trim($self['error']) . " (Hint: Does the name you're trying to insert already exist?)\");"; } else { $js .= "removeElement('{$window_name}');"; $js .= "xajax_window_submit('app_dns_view_list', xajax.getFormValues('app_dns_view_list_filter_form'), 'display_list');"; } // Return some javascript to the browser $response->addScript($js); return $response->getXML(); }
function tag_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.01'; printmsg("DEBUG => tag_add({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Possible types $allowed_types = array('subnet', 'host'); $typetext = implode(', ', $allowed_types); // Return the usage summary if we need to if ($options['help'] or !($options['type'] and $options['name'] and $options['reference'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM tag_add-v{$version} Adds a tag into the database assigned to the specified type of data. Synopsis: tag_add [KEY=VALUE] ... Required: name=STRING Name of new tag. type=STRING Type of thing to tag, Possible types listed below. reference=ID|STRING Reference to apply the tag to. ID or name used to find a record to attatch to. Possible types of tags: {$typetext} EOM ); } // Check if provided type is in the allowed types $options['type'] = strtolower(trim($options['type'])); if (!in_array($options['type'], $allowed_types)) { $self['error'] = "ERROR => Invalid tag type: {$options['type']}"; printmsg($self['error'], 0); return array(1, $self['error'] . "\n"); } // The formatting rule on tag input $options['name'] = preg_replace('/\\s+/', '-', trim($options['name'])); if (preg_match('/[@$%^*!\\|,`~<>{}]+/', $options['name'])) { $self['error'] = "ERROR => Invalid character in tag name"; printmsg($self['error'], 0); return array(1, $self['error'] . "\n"); } $options['reference'] = trim($options['reference']); // Use the find functions based on the type // this requires allowed types to have an 'ona_find_' related function eval("list(\$status, \$rows, \$reference) = ona_find_" . $options['type'] . "('" . $options['reference'] . "');"); if ($status or !$rows) { $self['error'] = "ERROR => Unable to find a {$options['type']} matching {$options['reference']}"; printmsg($self['error'], 0); return array(1, $self['error'] . "\n"); } // Validate that there isn't already an tag of this type associated to the reference list($status, $rows, $tags) = db_get_records($onadb, 'tags', array('type' => $options['type'], 'reference' => $reference['id'])); foreach ($tags as $t) { if (in_array($options['name'], $t)) { printmsg("DEBUG => The tag {$options['name']} is already associated with this {$options['type']}!", 3); $self['error'] = "ERROR => The tag {$options['name']} is already associated with this {$options['type']}!"; return array(3, $self['error'] . "\n"); } } // Check permissions if (!(auth('subnet_add') or auth('host_add'))) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // Get the next ID for the new tag $id = ona_get_next_id('tags'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } printmsg("DEBUG => ID for new tag: {$id}", 3); // Add the tag list($status, $rows) = db_insert_record($onadb, 'tags', array('id' => $id, 'name' => $options['name'], 'type' => $options['type'], 'reference' => $reference['id'])); if ($status or !$rows) { $self['error'] = "ERROR => tag_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => {$options['type']} TAG ADDED: {$options['name']} to {$reference['name']}({$reference['id']})."; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
function block_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.00'; printmsg("DEBUG => block_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['name'] and $options['start'] and $options['end'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM block_add-v{$version} Adds a block into the database Synopsis: block_add [KEY=VALUE] ... Required: name=STRING block name start=IP block start IP end=IP block end IP Optional: notes=STRING notes EOM ); } // The formatting rule on block names is all upper and trim it $options['name'] = trim($options['name']); $options['name'] = preg_replace('/\\s+/', '-', $options['name']); $options['name'] = strtoupper($options['name']); $options['start'] = ip_mangle($options['start'], 1); $options['end'] = ip_mangle($options['end'], 1); // 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']); // check to see if the campus already exists list($status, $rows, $block) = ona_get_block_record(array('name' => $options['name'])); if ($status or $rows) { $self['error'] = "ERROR => The block {$options['name']} already exists!"; printmsg("DEBUG => The block {$options['name']} already exists!", 3); return array(3, $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 for the new block $id = ona_get_next_id('blocks'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id() call failed!"; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } printmsg("DEBUG => ID for new block: {$id}", 3); // Add the block list($status, $rows) = db_insert_record($onadb, 'blocks', array('id' => $id, 'name' => $options['name'], 'ip_addr_start' => $options['start'], 'ip_addr_end' => $options['end'], 'notes' => $options['notes'])); if ($status or !$rows) { $self['error'] = "ERROR => block_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => Block ADDED: {$options['name']}"; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
function interface_add($options = "") { global $conf, $self, $onadb; printmsg("DEBUG => interface_add({$options}) called", 3); // Version - UPDATE on every edit! $version = '1.11'; // 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['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 interface_add-v{$version} Adds a new interface to an existing host record Synopsis: interface_add [KEY=VALUE] ... Required: host=NAME[.DOMAIN] or ID hostname or ID new interface is associated with ip=ADDRESS ip address (numeric or dotted) Optional: mac=ADDRESS mac address (most formats are ok) name=NAME interface name (i.e. "FastEthernet0/1.100") description=TEXT brief description of the interface natip=ADDRESS IP of NAT address to add with this new interface addptr Auto add a PTR record for new IP Notes: * DOMAIN will default to {$conf['dns_defaultdomain']} if not specified EOM ); } // clean up what is passed in $options['ip'] = trim($options['ip']); // Set options[force] to N if it's not set $options['force'] = sanitize_YN($options['force'], 'N'); // Set options[addptr] and options[create_a] to Y if they're not set $options['addptr'] = sanitize_YN($options['addptr'], 'Y'); // Warn about 'name' and 'description' fields exceeding max lengths if ($options['force'] == 'N') { 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"); } } // Find the Host they are looking for list($status, $rows, $host) = ona_find_host($options['host']); if (!$host['id']) { printmsg("DEBUG => The host specified, {$options['host']}, does not exist!", 3); $self['error'] = "ERROR => The host specified, {$options['host']}, does not exist!"; return array(2, $self['error'] . "\n"); } printmsg("DEBUG => Host selected: {$options['host']}", 3); // Translate IP address to a number $orig_ip = $options['ip']; $options['ip'] = ip_mangle($options['ip'], 1); if ($options['ip'] == -1) { printmsg("DEBUG => Invalid IP address ({$orig_ip})", 3); $self['error'] = "ERROR => Invalid IP address ({$orig_ip})!"; return array(3, $self['error'] . "\n"); } // Validate that there isn't already another interface with the same IP address list($status, $rows, $interface) = ona_get_interface_record("ip_addr = {$options['ip']}"); if ($rows) { printmsg("DEBUG => IP conflict: That IP address (" . ip_mangle($orig_ip, 'dotted') . ") is already in use!", 3); $self['error'] = "ERROR => 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"); } // 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['ip']}' AND ip_addr_end >= '{$options['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'] . "\nINFO => Conflicting DHCP pool record ID: {$pool['id']}\n"); } // Find the Subnet ID to use from the IP address list($status, $rows, $subnet) = ona_find_subnet($options['ip']); if ($status or $rows != 1 or !$subnet['id']) { 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(6, $self['error'] . "\n"); } printmsg("DEBUG => Subnet selected: {$subnet['description']}", 3); // Validate that the IP address supplied isn't the base or broadcast of the subnet, as long as it is not /32 or /31 if ($subnet['ip_mask'] < 4294967294) { if ($options['ip'] == $subnet['ip_addr']) { printmsg("DEBUG => IP address (" . ip_mangle($orig_ip, 'dotted') . ") can't be a subnet's base address!{$subnet['ip_addr']}", 3); $self['error'] = "ERROR => IP address (" . ip_mangle($orig_ip, 'dotted') . ") can't be a subnet's base address!"; return array(7, $self['error'] . "\n"); } if ($options['ip'] == 4294967295 - $subnet['ip_mask'] + $subnet['ip_addr']) { 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(8, $self['error'] . "\n"); } } // Remove any MAC address formatting if ($options['mac']) { $options['mac'] = trim($options['mac']); $orig_mac = $options['mac']; $options['mac'] = mac_mangle($options['mac'], 1); if ($options['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(10, $self['error'] . "\n"); } // Unless they have opted to allow duplicate mac addresses ... if ($options['force'] == 'N') { // 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, $interface) = db_get_record($onadb, 'interfaces', "mac_addr LIKE '{$options['mac']}' AND host_id != {$host['id']}"); if ($status or $rows) { printmsg("DEBUG => MAC conflict: That MAC address ({$options['mac']}) is already in use on another host!", 3); $self['error'] = "WARNING => MAC conflict: That MAC address ({$options['mac']}) is already in use on another host!"; return array(11, $self['error'] . "\n" . "NOTICE => You may ignore this warning and add the interface anyway with the \"force=yes\" option.\n" . "INFO => Conflicting interface record ID: {$interface['id']}\n"); } } } else { $options['mac'] = ''; } if (!$options['name']) { $options['name'] = ''; } // Check permissions if (!auth('host_add')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(12, $self['error'] . "\n"); } // Get the next ID for the new interface $id = ona_get_next_id('interfaces'); if (!$id) { $self['error'] = "ERROR => The ona_get_next_id('interfaces') call failed!"; printmsg($self['error'], 0); return array(13, $self['error'] . "\n"); } printmsg("DEBUG => ID for new interface: {$id}", 3); // Add the interface list($status, $rows) = db_insert_record($onadb, 'interfaces', array('id' => $id, 'host_id' => $host['id'], 'subnet_id' => $subnet['id'], 'ip_addr' => $options['ip'], 'mac_addr' => $options['mac'], 'name' => trim($options['name']), 'description' => trim($options['description']))); if ($status or !$rows) { $self['error'] = "ERROR => interface_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(14, $self['error'] . "\n"); } // Run the module to add a PTR record if requested if ($options['addptr'] == 'Y') { $ptropts['name'] = $host['fqdn']; $ptropts['ip'] = $options['ip']; $ptropts['view'] = $options['view']; $ptropts['type'] = 'PTR'; printmsg("DEBUG => interface_add() calling dns_record_add() for new PTR record: {$options['ip']}", 3); list($status, $output) = run_module('dns_record_add', $ptropts); if ($status) { return array($status, $output); } $self['error'] .= $output; } // if natip is passed, add the nat interface first if ($options['natip']) { $natint['ip'] = $id; $natint['natip'] = $options['natip']; printmsg("DEBUG => interface_add() calling nat_add() for new ip: {$options['natip']}", 3); list($status, $output) = run_module('nat_add', $natint); if ($status) { return array($status, $output); } $self['error'] .= $output; } // Return the success notice $self['error'] = "INFO => Interface ADDED: " . ip_mangle($options['ip'], 'dotted'); printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }