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"); }
/** * Ecache Plugin Convert (Block) Function */ function convert() { global $vars, $defaultpage; $args = func_get_args(); if (func_num_args() == 0) { return 'ecache(): no arugment.'; } $body = array_pop($args); $body = str_replace("\r", "\n", $body); //multiline arg has \r parse_options($args, $this->options); $this->options['page'] = isset($this->options['page']) ? $this->options['page'] : (isset($vars['page']) ? $vars['page'] : $defaultpage); return $this->ecache($this->options['page'], $body, $this->options['reset']); }
function mangle_ip($options) { global $conf, $self; printmsg('DEBUG => mangle_ip(' . $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['ip']) { $self['error'] = 'ERROR => Insufficient parameters'; // NOTE: Help message lines should not exceed 80 characters for proper display on a console return array(1, <<<EOM mangle_ip v{$version} Converts between various IP address representations Synopsis: mangle_ip(OPTIONS) Required: ip=<inet_addr> 32 or 128-bit Internet address Optional: format=<specifier> Desired output format, specified as a string numeric : return ip as an integer dotted : return ip as an IPv4 address cidr : return ip as a CIDR netmask binary : return ip as a 32-bit binary string bin128 : return ip as a 128-bit binary string ipv6 : return ip as an IPv6 address ipv6gz : return ip as a compressed IPv6 address EOM ); } // Now what? We need to call ip_mangle() with our options if (!$options['format']) { $options['format'] = 'default'; } $retval = ip_mangle($options['ip'], $options['format']) . "\n"; if ($self['error'] != '') { return array(1, $self['error'] . "\n"); } else { return array(0, $retval); } }
function convert() { $args = func_get_args(); ///// Support old versions (The 1st arg is tagtok) /// $fisrtIsOption = FALSE; foreach ($this->options as $key => $val) { if (!isset($args) && strpos($args[0], $key) === 0) { $firstIsOption = TRUE; break; } } if (func_num_args() >= 1 && !$firstIsOption) { $this->options['tag'] = array_shift($args); } ////////////////////////////////////////////////////// parse_options($args, $this->options); return $this->taglist($this->options['tag'], $this->options['related']); }
function convert() { $args = func_get_args(); parse_options($args, $this->options); if ($this->options['limit'] === "0") { $this->options['limit'] = NULL; } if ($this->options['cloud'] === 'off' || $this->options['cloud'] === 'false') { $this->options['cloud'] = FALSE; } //print_r($this->options); if ($this->options['cloud']) { $html = $this->plugin_tag->display_tagcloud($this->options['limit'], $this->options['related']); } else { $html = $this->plugin_tag->display_taglist($this->options['limit'], $this->options['related']); } return $html; }
/** * Main functions. Just decides what mode we are in and calls the * appropriate methods. */ function main() { global $info, $config; $args = Console_Getopt::readPHPArgv(); if (count($args) < 2) { print_usage_info(); } if (substr($args[1], 0, 1) == "-" || substr($args[1], 0, 1) == "/") { print "invalid parameter " . $args[2] . "\n"; print_usage_info(); } if (substr($args[1], -4) == ".php") { // mode 2: create zombie app if (!file_exists($args[1])) { die("config file " . $args[1] . " does not exist\n"); } read_config_file($args[1]); $outdir = ZOMBIE_BASE . '/../' . Horde_String::lower($config['app']); if (is_dir($outdir) && $args[2] != "-f") { print "Directory {$outdir} already exists.\nUse -f flag to force overwrite\n"; exit; } $n = $config['app']; print "Creating Horde Application {$n} in directory " . Horde_String::lower($n) . "\n"; transform($outdir); print "\nHorde Application '{$n}' successfully written. Where to go from here:\n" . "1) Paste content of {$n}/registry.stub to horde/config/registry.php.\n" . " After that, the {$n} should be working!\n" . "2) Replace {$n}.gif with proper application icon\n" . "3) Ensure conf.php is not world-readable as it may contain password data.\n" . "4) Start playing around and enhancing your new horde application. Enjoy!\n"; } else { // mode 1: create config file parse_options($args); print "creating config file for table " . $config['table'] . "\n"; create_table_info(); enhance_info(); print "writing config file to " . $config['file'] . "\n"; dump_config_file(); } }
if (false === $status) { $errors = $restore->getErrors(); if (count($errors) > 0) { $errorMsg = 'Errors were encountered: ' . implode(', ', $errors) . ' If seeking support please click to Show Advanced Details above and provide a copy of the log.'; pb_backupbuddy::status('error', $errorMsg); } else { $errorMsg = 'Error #894383: Unknown error starting restore. See advanced status log for details.'; } pb_backupbuddy::alert($errorMsg); return; } $restore->_state['defaultURL'] = $restore->getDefaultUrl(); $restore->_state['defaultDomain'] = $restore->getDefaultDomain(); if ('true' != pb_backupbuddy::_GET('deploy')) { // deployment mode pre-loads state data in a file instead of passing via post. $restore->_state = parse_options($restore->_state); } $restore->_state['skipUnzip'] = $skipUnzip; // Set up state variables. if ('db' == $restore->_state['dat']['backup_type'] || false == $restore->_state['restoreFiles']) { pb_backupbuddy::status('details', 'Database backup OR not restoring files.'); $restore->_state['tempPath'] = ABSPATH . 'importbuddy/temp_' . pb_backupbuddy::random_string(12) . '/'; $restore->_state['restoreFileRoot'] = $restore->_state['tempPath']; pb_backupbuddy::anti_directory_browsing($restore->_state['restoreFileRoot'], $die = false); } else { pb_backupbuddy::status('details', 'Restoring files.'); $restore->_state['restoreFileRoot'] = ABSPATH; // Restore files into current root. } // Parse submitted options for saving to state. function parse_options($restoreData)
<?php if (!defined('PB_IMPORTBUDDY') || true !== PB_IMPORTBUDDY) { die('<html></html>'); } Auth::require_authentication(); // Die if not logged in. $data = array('step' => '4'); pb_backupbuddy::set_greedy_script_limits(true); parse_options(); /** * parse_options() * * Parses various submitted options and settings from step 1. * * @return null */ function parse_options() { if (isset($_POST['siteurl'])) { pb_backupbuddy::$options['siteurl'] = $_POST['siteurl']; if (isset($_POST['custom_home'])) { pb_backupbuddy::$options['home'] = $_POST['home']; } else { pb_backupbuddy::$options['home'] = $_POST['siteurl']; } } // end isset post siteurl. if (isset($_POST['skip_database_import']) && $_POST['skip_database_import'] == 'on') { pb_backupbuddy::$options['skip_database_import'] = true; } else {
function ona_sql($options = "") { // The important globals global $conf, $onadb, $base; // Version - UPDATE on every edit! $version = '1.05'; // TODO: Maybe make this into a sys_config option $srvdir = dirname($base) . "/sql"; printmsg('DEBUG => ona_sql(' . $options . ') called', 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize delimeter if (!$options['delimiter']) { $options['delimiter'] = ':'; } // fix up the escaped ' marks. may need the = and & stuff too???? $options['sql'] = str_replace('\\\'', '\'', $options['sql']); $options['sql'] = str_replace('\\=', '=', $options['sql']); // Set "options[commit] to no if it's not set if (!array_key_exists('commit', $options)) { $options['commit'] = 'N'; } else { $options['commit'] = sanitize_YN($options['commit'], 'N'); } // Set "options[commit] to no if it's not set if (!array_key_exists('dataarray', $options)) { $options['dataarray'] = 'N'; } else { $options['dataarray'] = sanitize_YN($options['dataarray'], 'N'); } // Set "options[header] to yes if it's not set if (!array_key_exists('header', $options)) { $options['header'] = 'Y'; } else { $options['header'] = sanitize_YN($options['header'], 'Y'); } // Check permissions if (!auth('ona_sql')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // Return the usage summary if we need to if ($options['help'] or !($options['list'] and !$options['sql'] or !$options['list'] and $options['sql'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console return array(1, <<<EOM ona_sql-v{$version} Runs the specified SQL query on the database and prints the result Synopsis: ona_sql [KEY=VALUE] ... Required: sql=STATEMENT|FILENAME quoted SQL statement to execute OR list lists the SQL files available on the server side Optional: show displays contents of SQL, gives usage etc commit=yes|no commit the transaction (no) header=yes|no display record header (yes) delimiter=DELIMITER record delimiter for output (:) (1,2,..)=VALUE bind variables, replaces ? in query sequentially. the first ? found is replaced by 1=value, and so on Notes: * Query is sent to the configured OpenNetAdmin database server. * The use of bind variables requires your options to match positionally. * The SQL option will be tried first as a local file, then as a server file, then as a raw text SQL query. Filenames are case sensitive. * Server based SQL files are located in {$srvdir} * Some plugins may provide their own SQL dir inside the plugin directory * Use the show option to display contents of SQL files, this should contain a long description and any usage information that is needed. EOM ); } // TODO: check that the user has admin privs? or at least a ona_sql priv // Get a list of the files $plugins = plugin_list(); $files = array(); $srvdirs = array(); array_push($srvdirs, $srvdir); // add a local sql dir as well so they don't get overrriden by installs array_push($srvdirs, dirname($base) . '/www/local/sql'); // loop through the plugins and find files inside of their sql directories. foreach ($plugins as $plug) { array_push($srvdirs, $plug['path'] . '/sql'); } // Loop through each of our plugin directories and the default directory to find .sql files foreach ($srvdirs as $srvdir) { if ($handle = @opendir($srvdir)) { while (false !== ($file = readdir($handle))) { if ($file != "." && $file != ".." && substr($file, -4) == '.sql') { // Build an array of filenames array_push($files, $srvdir . '/' . $file); } } closedir($handle); } } // sort the file names asort($files); // List the sql files on the server side if ($options['list'] == 'Y') { $text .= sprintf("\n%-25s%s\n", 'FILE', 'DESCRIPTION'); $text .= sprintf("%'-80s\n", ''); // Loop through and display info about the files foreach ($files as $file) { // Open the file and get the first line, this is the short description $fh = fopen($file, 'r'); $desc = rtrim(fgets($fh)); fclose($fh); // Print the info $text .= sprintf("%-25s%s\n", basename($file), $desc); } $text .= "\n"; return array(0, $text); } // Check that the sql variable passsed matches a file name locally, if it does, open it and replace $options['sql'] with it // Loop through files array till we find the right file $foundfile = false; foreach ($files as $file) { if (strstr($file, $options['sql'])) { $options['sql'] = trim(file_get_contents($file)); $foundfile = true; } } // if we have not found a file on the server and the sql option does end in .sql then print a message that we coulnt find a file // otherwise assume it is a sql statement being passed at the cli if ($foundfile == false and substr($options['sql'], -4) == '.sql') { $self['error'] = "ERROR => Unable to find specified SQL stored on server: {$options['sql']}"; printmsg($self['error'], 2); return array(10, $self['error'] . "\n"); } // Show the contents of the sql query for usage info etc. if ($options['show'] == 'Y') { $text .= $options['sql'] . "\n\n"; return array(0, $text); } // Count how many ?s there are in the sql query. that must match how many sqlopts are passed // if this is an oracle database you could change the ? to a :.. more work on this however needs to be done $qvars = substr_count($options['sql'], '?'); // loop through the options based on how many qvars are in the sql statement. print an error if we didnt // get a variable to use in the sql statement for ($i = 1; $i <= $qvars; $i++) { if (!array_key_exists($i, $options)) { $self['error'] = "ERROR => You did not supply a value for bind variable {$i}!"; printmsg($self['error'], 2); return array(10, $self['error'] . "\n"); } // assign the variables to sqlopts $sqlopts[$i] = $options[$i]; } // One last check to be sure // Count how many times ? is in the sql statement. there should be that many elements in sqlopts if (count($sqlopts) != $qvars) { $self['error'] = "ERROR => SQL query and bind variable count did not match."; printmsg($self['error'], 2); return array(1, $self['error'] . "\n"); } printmsg("DEBUG => [ona_sql] Running SQL query: {$options['sql']}", 5); // Run the query $rs = $onadb->Execute($options['sql'], $sqlopts); if ($rs === false) { $self['error'] = "ERROR => SQL query failed: " . $onadb->ErrorMsg() . "\n"; return array(2, $self['error']); } $text = ""; $dataarr = array(); // If we got a record, that means they did a select .. display it if ($rs->RecordCount()) { $build_header = 1; $i = 0; // Loop through each record returned by the sql query while (!$rs->EOF) { $i++; $record = $rs->FetchRow(); $dataarr[$i] = $record; // Build the header if we need to if ($build_header == 1 and $options['header'] == 'Y') { $build_header = 0; foreach (array_keys($record) as $key) { $text .= $key . $options['delimiter']; } $text = preg_replace("/{$options['delimiter']}\$/", "", $text); $text .= "\n"; } // Display the row foreach (array_keys($record) as $key) { $text .= $record[$key] . $options['delimiter']; } $text = preg_replace("/{$options['delimiter']}\$/", "", $text); $text .= "\n"; } } else { $text .= "NOTICE => SQL executed successfully - no records returned\n"; } // If we want the recordset returned instead of the text if ($options['dataarray'] == 'Y') { return array(0, $dataarr); } // Unless the user said YES to commit, return a non-zero // exit status so that module_run.php doesn't commit the DB transaction. $return = 1; if ($options['commit'] == 'Y') { $return = 0; } return array($return, $text); }
function add_module($options = "") { global $conf, $self, $onadb; printmsg('DEBUG => add_module(' . $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_module-v{$version} Registers a new DCM module, this should be used by install scripts that are creating new functionality that requires a registered module. Synopsis: add_module(OPTIONS) Options: name=STRING Name of DCM module desc=STRING Quoted string to describe this module file=STRING Path to php file, relative to {$conf['dcm_module_dir']} EOM ); } // Get a list of the valid "modules" and their descriptions. list($status, $rows, $modules) = db_get_record($onadb, 'dcm_module_list', array('name' => $options['name']), ''); if ($rows) { $self['error'] = "ERROR => add_module() Module name already exists: {$options['name']}"; printmsg($self['error'], 0); return array(1, $self['error'] . "\n"); } // Add the record list($status, $rows) = db_insert_record($onadb, 'dcm_module_list', array('name' => $options['name'], 'description' => $options['desc'], 'file' => $options['file'])); if ($status or !$rows) { $self['error'] = "ERROR => add_module() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(2, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => Module ADDED: {$options['name']} [{$options['desc']}] => {$options['file']}"; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); }
function main() { assert(pcntl_signal(SIGINT, 'handle_sigint')); parse_options(); echo "-- Simple DBGp Client --\n"; global $conn; // Start the listening socket. list($socket, $port) = start_client($conn->port); echo "Listening on port {$port}\n"; // Accept a connection. $fd = null; while (true) { $fd = @socket_accept($socket); if ($fd !== false) { echo "Connected to an XDebug server!\n"; break; } } socket_close($socket); $conn->fd = $fd; while (true) { // Wait for the expected number of responses. Normally we expect 1 // response, but with the break command, we expect 2. $responses = ""; while ($conn->expect_responses > 0) { $response = read_response($fd); if (starts_with($response, "Client socket error")) { break; } // Init packet doesn't end in </response>. $conn->expect_responses -= substr_count($response, "</response>"); $conn->expect_responses -= substr_count($response, "</init>"); $responses .= $response; } $conn->expect_responses = 1; // Might have been sent a Ctrl-c while waiting for the response. if ($conn->send_break) { send_command($fd, "break -i SIGINT"); $conn->send_break = false; // We're expecting a response for the break command, and the command // before the break command. $conn->expect_responses = 2; continue; } // Echo back the response to the user if it isn't a stream. if (!is_stream($responses)) { echo "{$responses}\n"; } // Received response saying we're stopping. if (strpos($responses, "status=\"stopped\"") > 0) { echo "-- Request ended, stopping --\n"; break; } // Get a command from the user and send it. $line = readline("(dbgp) \$ "); $line = trim($line); if ($line === "") { continue; } if (starts_with("quit", $line)) { echo "-- Quitting, request will continue running --\n"; break; } send_command($fd, $line); } socket_close($fd); $conn->fd = null; }
function vlan_campus_display($options = "") { global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.00'; printmsg("DEBUG => vlan_campus_display({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[verbose] (default is yes) $options['verbose'] = sanitize_YN($options['verbose'], 'Y'); // Return the usage summary if we need to if ($options['help'] or !$options['campus']) { // 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_display-v{$version} Displays a vlan campus record from the database Synopsis: vlan_campus_display [KEY=VALUE] ... Required: campus=NAME or ID Campus name or ID of the campus display Optional: verbose=[yes|no] Display additional info (DEFAULT: yes) EOM ); } // The formatting rule on campus names is all upper and trim it $options['campus'] = strtoupper(trim($options['campus'])); // If the campus provided is numeric, check to see if it's valid if (is_numeric($options['campus'])) { // See if it's an vlan_campus_id list($status, $rows, $campus) = ona_get_vlan_campus_record(array('id' => $options['campus'])); if (!$campus['id']) { printmsg("DEBUG => Unable to find campus using the ID {$options['campus']}!", 3); $self['error'] = "ERROR => Unable to find campus using the ID {$options['campus']}!"; return array(2, $self['error'] . "\n"); } } else { list($status, $rows, $campus) = ona_get_vlan_campus_record(array('name' => $options['campus'])); if (!$campus['id']) { $self['error'] = "ERROR => Unable to find campus using the name {$options['campus']}!"; printmsg("DEBUG => Unable to find campus using the name {$options['campus']}!", 3); return array(2, $self['error'] . "\n"); } } printmsg("DEBUG => Found campus: {$campus['name']}", 3); // Build text to return $text = "VLAN CAMPUS RECORD\n"; $text .= format_array($campus); // If 'verbose' is enabled, grab some additional info to display if ($options['verbose'] == 'Y') { // vlan record(s) $i = 0; do { list($status, $rows, $vlan) = ona_get_vlan_record(array('vlan_campus_id' => $campus['id'])); if ($rows == 0) { break; } $i++; $text .= "\nASSOCIATED VLAN RECORD ({$i} of {$rows})\n"; $text .= format_array($vlan); } while ($i < $rows); } // Return the success notice return array(0, $text); }
function dhcp_lease_add($options = "") { // The important globals global $conf, $self, $mysql; // Version - UPDATE on every edit! $version = '1.00'; printmsg("DEBUG => dhcp_lease_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['raw'] or $options['ip'] and $options['mac'])) { // 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_lease_add-v{$version} Adds a dhcp lease entry into the tracking database Synopsis: dhcp_lease_add [KEY=VALUE] ... Required: raw=TEXT The raw text from the DHCP log Notes: Adding a lease here does NOT effect the actual functioning DHCP server. This is purely to keep track of lease information derived from the DHCP logfile itself. EOM ); } $name = 'N/A'; if ($options['raw']) { // break the line down into its parts $line = preg_split("/( on | to | via )/", $options['raw']); $mac = $line[2]; $iptext = $line[1]; $ip = ip_mangle($iptext, 'numeric'); // if the second field has mac and a name in parens then break it out if (strpos($line[2], '(')) { list($mac, $name) = split('[()]', $line[2]); $name = trim($name); } // make sure the mac has been trimmed $mac = trim($mac); $text = "DHCP Lease Add: IP={$ip} IPTEXT={$line[1]} MAC={$mac} NAME={$name}\n"; printmsg("DEBUG => {$text}", 3); } if ($options['ip'] and $options['mac']) { $ip = ip_mangle($options['ip'], 'numeric'); // make sure the mac has been trimmed $mac = trim($options['mac']); if ($options['name']) { $name = $options['name']; } $text = "DHCP Lease Add: IP={$ip} IPTEXT={$line[1]} MAC={$mac} NAME={$name}\n"; printmsg("DEBUG => {$text}", 3); } // Check to see if the IP is already in the database // list($status, $rows, $lease) = db_get_record($mysql, "dhcp_leases", array('IP_ADDRESS' => $ip)); // if ($rows) { // printmsg("DEBUG => updating existing record", 2); // list($status, $rows) = db_update_record($mysql, "dhcp_leases", array('IP_ADDRESS' => $ip), array('MAC' => $mac, 'HOSTNAME' => $name)); // } else { // printmsg("DEBUG => inserting new record", 2); // list($status, $rows) = db_insert_record($mysql, "dhcp_leases", array('IP_ADDRESS' => $ip, // 'IP_TEXT' => $iptext, // 'MAC' => $mac, // 'HOSTNAME' => $name) // ); // } // Return the success notice return array(0, $text); }
function build_bind_domain($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.50'; printmsg("DEBUG => build_bind_domain({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !$options['domain']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOF build_bind_domain-v{$version} Builds a zone file for a dns server from the database Synopsis: build_bind_domain [KEY=VALUE] ... Required: domain=DOMAIN or ID build zone file for specified domain EOF ); } // Get the domain information list($status, $rows, $domain) = ona_find_domain($options['domain']); printmsg("DEBUG => build_bind_domain() Domain record: {$domain['domain']}", 3); if (!$domain['id']) { printmsg("DEBUG => Unknown domain record: {$options['domain']}", 3); $self['error'] = "ERROR => Unknown domain record: {$options['domain']}"; return array(2, $self['error'] . "\n"); } // if for some reason the domains default_ttl is not set, use the one from the $conf['dns']['default_ttl'] if ($domain['default_ttl'] == 0) { $domain['default_ttl'] = $conf['dns']['default_ttl']; } if ($domain['primary_master'] == '') { $domain['primary_master'] = 'localhost'; } // loop through records and display them $q = "\n SELECT *\n FROM dns\n WHERE domain_id = {$domain['id']}\n ORDER BY type"; // exectue the query $rs = $onadb->Execute($q); if ($rs === false or !$rs->RecordCount()) { $self['error'] = 'ERROR => build_zone(): SQL query failed: ' . $onadb->ErrorMsg(); printmsg($self['error'], 0); $exit += 1; } $rows = $rs->RecordCount(); // check if this is a ptr domain that has delegation if (strpos(str_replace('in-addr.arpa', '', $domain['fqdn']), '-')) { $ptrdelegation = true; } // Start building the named.conf - save it in $text $text = "; DNS zone file for {$domain['fqdn']} built on " . date($conf['date_format']) . "\n"; // print the opening host comment with row count $text .= "; TOTAL RECORDS (count={$rows})\n\n"; // FIXME: MP do more to ensure that dots are at the end as appropriate $text .= "\$ORIGIN {$domain['fqdn']}.\n"; $text .= "\$TTL {$domain['default_ttl']}\n"; $text .= ";Serial number is current unix timestamp (seconds since UTC)\n\n"; // NOTE: There are various ways that one could generate the serial. The bind book suggests YYYYMMDDXX where XX is 1/100th of the day or some counter in the day. // I feel this is too limiting. I prefer the Unix timestamp (seconds since UTC) method. TinyDNS uses this method as well and it allows for much more granularity. // Referr to the following for some discussion on the topic: http://www.lifewithdjbdns.com/#Migration // NOTE: for now I am generating the serial each time the zone is built. I'm ignoring, and may remove, the one stored in the database. $serial_number = time(); // Build the SOA record // FIXME: MP do a bit more to ensure that dots are where they should be $text .= "@ IN SOA {$domain['primary_master']}. {$domain['admin_email']} ({$serial_number} {$domain['refresh']} {$domain['retry']} {$domain['expiry']} {$domain['minimum']})\n\n"; // Loop through the record set while ($dnsrecord = $rs->FetchRow()) { // Dont build records that begin in the future if (strtotime($dnsrecord['ebegin']) > time()) { continue; } if (strtotime($dnsrecord['ebegin']) < 0) { continue; } // If there are notes, put the comment character in front of it if ($dnsrecord['notes']) { $dnsrecord['notes'] = '; ' . str_replace("\n", "; ", $dnsrecord['notes']); } // If the ttl is empty then make it truely empty if ($dnsrecord['ttl'] == 0) { $dnsrecord['ttl'] = ''; } // Also, if the records ttl is the same as the domains ttl then dont display it, just to keep it "cleaner" if (!strcmp($dnsrecord['ttl'], $domain['default_ttl'])) { $dnsrecord['ttl'] = ''; } // Dont print a dot unless hostname has a value if ($dnsrecord['name']) { $dnsrecord['name'] = $dnsrecord['name'] . '.'; } if ($dnsrecord['type'] == 'A') { // Find the interface record list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id'])); if ($status or !$rows) { printmsg("ERROR => Unable to find interface record!", 3); $self['error'] = "ERROR => Unable to find interface record!"; return array(5, $self['error'] . "\n"); } $fqdn = $dnsrecord['name'] . $domain['fqdn']; $text .= sprintf("%-50s %-8s IN %-8s %-30s %s\n", $fqdn . '.', $dnsrecord['ttl'], $dnsrecord['type'], $interface['ip_addr_text'], $dnsrecord['notes']); } if ($dnsrecord['type'] == 'PTR') { // Find the interface record list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id'])); if ($status or !$rows) { printmsg("ERROR => Unable to find interface record!", 3); $self['error'] = "ERROR => Unable to find interface record!"; return array(5, $self['error'] . "\n"); } // Get the name info that the cname points to list($status, $rows, $ptr) = ona_get_dns_record(array('id' => $dnsrecord['dns_id']), ''); // If this is a delegation domain, find the subnet cidr if ($ptrdelegation) { list($status, $rows, $subnet) = ona_get_subnet_record(array('id' => $interface['subnet_id'])); $ip_last = ip_mangle($interface['ip_addr'], 'flip'); $ip_last_digit = substr($ip_last, 0, strpos($ip_last, '.')); $ip_remainder = substr($ip_last, strpos($ip_last, '.')) . '.in-addr.arpa.'; $text .= sprintf("%-50s %-8s IN %-8s %s.%-30s %s\n", $ip_last_digit . '-' . ip_mangle($subnet['ip_mask'], 'cidr') . $ip_remainder, $dnsrecord['ttl'], $dnsrecord['type'], $ptr['name'], $ptr['domain_fqdn'] . '.', $dnsrecord['notes']); } else { $text .= sprintf("%-50s %-8s IN %-8s %s.%-30s %s\n", ip_mangle($interface['ip_addr'], 'flip') . '.in-addr.arpa.', $dnsrecord['ttl'], $dnsrecord['type'], $ptr['name'], $ptr['domain_fqdn'] . '.', $dnsrecord['notes']); } } if ($dnsrecord['type'] == 'CNAME') { // Find the interface record list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id'])); if ($status or !$rows) { printmsg("ERROR => Unable to find interface record!", 3); $self['error'] = "ERROR => Unable to find interface record!"; return array(5, $self['error'] . "\n"); } // Get the name info that the cname points to list($status, $rows, $cname) = ona_get_dns_record(array('id' => $dnsrecord['dns_id']), ''); $fqdn = $dnsrecord['name'] . $domain['fqdn']; $text .= sprintf("%-50s %-8s IN %-8s %s.%-30s %s\n", $fqdn . '.', $dnsrecord['ttl'], $dnsrecord['type'], $cname['name'], $cname['domain_fqdn'] . '.', $dnsrecord['notes']); } if ($dnsrecord['type'] == 'NS') { // Find the interface record list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id'])); if ($status or !$rows) { printmsg("ERROR => Unable to find interface record!", 3); $self['error'] = "ERROR => Unable to find interface record!"; return array(5, $self['error'] . "\n"); } // Get the name info that the cname points to list($status, $rows, $ns) = ona_get_dns_record(array('id' => $dnsrecord['dns_id']), ''); $text .= sprintf("%-50s %-8s IN %-8s %s.%-30s %s\n", $domain['fqdn'] . '.', $dnsrecord['ttl'], $dnsrecord['type'], $ns['name'], $ns['domain_fqdn'] . '.', $dnsrecord['notes']); } if ($dnsrecord['type'] == 'MX') { // Find the interface record list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id'])); if ($status or !$rows) { printmsg("ERROR => Unable to find interface record!", 3); $self['error'] = "ERROR => Unable to find interface record!"; return array(5, $self['error'] . "\n"); } // Get the name info that the cname points to list($status, $rows, $mx) = ona_get_dns_record(array('id' => $dnsrecord['dns_id']), ''); if ($dnsrecord['name']) { $name = $dnsrecord['name'] . $domain['fqdn']; } else { $name = $domain['name']; } $text .= sprintf("%-50s %-8s IN %s %-5s %s.%-30s %s\n", $name . '.', $dnsrecord['ttl'], $dnsrecord['type'], $dnsrecord['mx_preference'], $mx['name'], $mx['domain_fqdn'] . '.', $dnsrecord['notes']); } if ($dnsrecord['type'] == 'SRV') { // Find the interface record list($status, $rows, $interface) = ona_get_interface_record(array('id' => $dnsrecord['interface_id'])); if ($status or !$rows) { printmsg("ERROR => Unable to find interface record!", 3); $self['error'] = "ERROR => Unable to find interface record!"; return array(5, $self['error'] . "\n"); } // Get the name info that the cname points to list($status, $rows, $srv) = ona_get_dns_record(array('id' => $dnsrecord['dns_id']), ''); if ($dnsrecord['name']) { $name = $dnsrecord['name'] . $domain['fqdn']; } else { $name = $domain['name']; } $text .= sprintf("%-50s %-8s IN %s %s %s %-8s %-30s %s\n", $name . '.', $dnsrecord['ttl'], $dnsrecord['type'], $dnsrecord['srv_pri'], $dnsrecord['srv_weight'], $dnsrecord['srv_port'], $srv['fqdn'] . '.', $dnsrecord['notes']); } if ($dnsrecord['type'] == 'TXT') { $fqdn = $dnsrecord['name'] . $domain['fqdn']; $text .= sprintf("%-50s %-8s IN %-8s %-30s %s\n", $fqdn . '.', $dnsrecord['ttl'], $dnsrecord['type'], '"' . $dnsrecord['txt'] . '"', $dnsrecord['notes']); } } ////////////// Footer stuff ////////////////// // MP: FIXME: For now I"m not using this.. bind errors out if the file doesnt exist. need a deterministic way to do this. // Allow for a local footer include.. I expect this to rarely be used // $text .= "\n; Allow for a local footer include.. I expect this to rarely be used.\n"; // $text .= "\$INCLUDE named-{$domain['fqdn']}-footer\n"; // Return the zone file return array(0, $text); }
function subnet_nextip($options = "") { global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.00'; printmsg('DEBUG => subnet_del(' . $options . ') called', 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[commit] (default is no) $options['commit'] = sanitize_YN($options['commit'], 'N'); // Return the usage summary if we need to if ($options['help'] 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 subnet_del-v{$version} Return the next available IP address on a subnet. Synopsis: subnet_nextip [KEY=VALUE] ... Required: subnet=IP or ID select subnet by search string Optional: offset=NUMBER Starting offset to find next available IP output=[dotted|numeric] Return the number as a dotted or numeric value DEFAULT: numeric EOM ); } // Find the subnet record we're deleting list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); if ($status or !$rows) { $self['error'] = "ERROR => Subnet not found"; return array(2, $self['error'] . "\n"); } // Create a few variables that will be handy later $num_ips = 0xffffffff - $subnet['ip_mask']; $last_ip = $subnet['ip_addr'] + $num_ips - 1; // check that offset is a number if (isset($options['offset']) and !is_numeric($options['offset'])) { $self['error'] = "ERROR => Offset must be a numeric number"; return array(3, $self['error'] . "\n"); } else { $offsetmsg = " beyond offset {$options['offset']}"; } // make sure the offset does not extend beyond the specified subnet if ($options['offset'] >= $num_ips - 1) { $self['error'] = "ERROR => Offset extends beyond specified subnet boundary"; return array(4, $self['error'] . "\n"); } if (!isset($options['output'])) { $options['output'] = '1'; } else { if ($options['output'] != 'dotted' && $options['output'] != 'numeric') { $self['error'] = "ERROR => Output option must be 'dotted' or 'numeric'"; return array(5, $self['error'] . "\n"); } } // Find the first number based on our subnet and offset $ip = $subnet['ip_addr'] + $options['offset']; // Make sure we skip past the subnet IP to the first usable IP if ($ip == $subnet['ip_addr']) { $ip++; } // Start looping through our IP addresses until we find an available one while ($ip <= $last_ip) { // Find out if the ip is used in an interface list($status, $rows, $interfaces) = db_get_records($onadb, 'interfaces', array('ip_addr' => $ip)); // If we find a free address.. check that it is not in a DHCP pool if (!$rows) { list($status, $rows, $pool) = db_get_record($onadb, 'dhcp_pools', "{$ip} >= ip_addr_start AND {$ip} <= ip_addr_end"); if ($rows) { $ip = $pool['ip_addr_end']; } else { break; } } $ip++; // increment by one and check again } // If we checked all the IPs, make sure we are not on the broadcast IP of the subnet if ($ip == $last_ip + 1) { $self['error'] = "ERROR => No available IP addresses found on subnet{$offsetmsg}"; return array(5, $self['error'] . "\n"); } // return the IP return array(0, ip_mangle($ip, $options['output']) . "\n"); }
function dhcp_server_del($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.03'; printmsg("DEBUG => dhcp_server_del({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[commit] (default is yes) $options['commit'] = sanitize_YN($options['commit'], 'N'); // 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_del-v{$version} Removes a subnet record from a DHCP server Synopsis: dhcp_server_del [KEY=VALUE] ... Required: subnet=NAME or ID subnet name or ID server=NAME[.DOMAIN] or ID server name or ID Optional: commit=[Y|N] commit db transaction (no) 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_del(): Found subnet, {$subnet['name']}", 3); if ($options['server']) { // 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"); } } //printmsg("DEBUG => dhcp_server_del(): Found server, {$host['FQDN']}", 3); // Test that this subnet is even 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 => Unable to find {$subnet['name']} on server {$host['fqdn']}", 3); $self['error'] = "ERROR => Unable to find {$subnet['name']} on server {$host['fqdn']}"; return array(11, $self['error'] . "\n"); } // If "commit" is yes, delete the record if ($options['commit'] == 'Y') { // Check permissions if (!auth('advanced') or !authlvl($host['LVL']) or !authlvl($subnet['LVL'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // check if allowed to remove subnet from server // check for pool assigned to the server itself list($status, $rows, $pools) = db_get_records($onadb, 'dhcp_pools', array('subnet_id' => $subnet['id'])); foreach ($pools as $pool) { if ($pool['dhcp_failover_group_id']) { $foundfg = 0; list($status, $rows, $primary) = ona_get_dhcp_failover_group_record(array('id' => $pool['dhcp_failover_group_id'], 'primary_server_id' => $host['id'])); if ($rows) { $foundfg++; } list($status, $rows, $secondary) = ona_get_dhcp_failover_group_record(array('id' => $pool['dhcp_failover_group_id'], 'secondary_server_id' => $host['id'])); if ($rows) { $foundfg++; } // if a subnet/server pair is found in dhcp pools, don't allow removal if ($foundfg > 0) { printmsg("DEBUG => Subnet ({$subnet['name']}) has a pool assigned to this Server ({$host['fqdn']}), which is part of a failover group. The server must be removed from the failover group first.", 3); $self['error'] = "ERROR => Subnet ({$subnet['name']}) has a pool assigned to this Server ({$host['fqdn']}), which is part of a failover group. The server must be removed from the failover group first."; return array(12, $self['error'] . "\n"); } } } // MP: remove this after testing. dhcp options should not stop us from dis-associating a subnet from a server // Not really sure why I have this.. probably left over cruft from old thoughts // // check if there are any DHCP parameters assigned to the subnet // list($status, $rows, $tmp) = ona_get_dhcp_option_entry_record(array('subnet_id' => $subnet['id'])); // // // if so, check that this is not the last DHCP server that services this subnet // if ($rows > 0) { // list($status, $rows, $tmp) = ona_get_dhcp_server_subnet_record(array('subnet_id' => $subnet['id'])); // // // If this is the last DHCP server that services this subnet, don't allow removal until DHCP parameters are removed // if($rows <= 1){ // printmsg("DEBUG => Subnet ({$subnet['name']}) has DHCP parameters assigned which need to be removed first",3); // $self['error'] = "ERROR => Subnet ({$subnet['name']}) has DHCP parameters assigned which need to be removed first"; // return(array(12, $self['error'] . "\n")); // } // } // delete record from dhcp_server_subnets list($status, $rows) = db_delete_records($onadb, 'dhcp_server_subnets', array('id' => $dhcpserver['id'])); if ($status) { $self['error'] = "ERROR => dhcp_server_del() SQL Query failed:" . $self['error']; printmsg($self['error'], 0); return array(9, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => DHCP Subnet/Server Pair DELETED: {$subnet['name']}/{$host['fqdn']} "; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); } // Otherwise display the record that would have been deleted $text = <<<EOL Record(s) NOT DELETED (see "commit" option) Displaying record(s) that would have been removed: {$subnet['name']} from: {$host['fqdn']} EOL; return array(6, $text); }
function main() { $opts = parse_options(); create_dirs($opts); $dbs = run('mysql ' . $opts['connection'] . ' -e "show databases" -B -N'); $seconds = array('hourly' => 60 * 60, 'daily' => 60 * 60 * 24, 'weekly' => 60 * 60 * 24 * 7, 'monthly' => 60 * 60 * 24 * 30, 'yearly' => 60 * 60 * 24 * 365.25); $time = time(); foreach ($dbs as $db) { $db = trim($db); if (array_search($db, $opts['exclude'])) { continue; } $old_file = false; foreach ($opts['keep'] as $name => $keep) { $dir = "{$opts['backup-dir']}/{$name}"; $minutes = $seconds[$name]; $files = run("ls -t {$dir} | grep '.{$db}.tar.gz'", true); if ($keep === -1 || empty($files) || $time - filemtime("{$dir}/{$files['0']}") >= $seconds[$name]) { $file = "{$dir}/" . strftime('%Y_%m_%d_%H:%M:%S') . "__{$db}.tar.gz"; if (empty($old_file)) { run("mysqldump {$opts['extra']} {$opts['connection']} {$db} | gzip -c > {$file}"); $old_file = $file; } else { run("cp {$old_file} {$file}"); $file = $old_file; } ok("Created {$name} backup {$file}"); if ($keep !== -1 && count($files) > $keep) { run("rm {$dir}/" . array_pop($files)); } } } } exit(0); }
function tag_del($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.00'; printmsg("DEBUG => tag_del({$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['tag']) { // 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_del-v{$version} Deletes an tag from the database Synopsis: tag_del [KEY=VALUE] ... Required: tag=ID ID of the tag to delete Optional: commit=[yes|no] commit db transaction (no) EOM ); } // Sanitize options[commit] (default is no) $options['commit'] = sanitize_YN($options['commit'], 'N'); // If the tag provided is numeric, check to see if it's an tag if (is_numeric($options['tag'])) { // See if it's a tag_id list($status, $rows, $tag) = db_get_record($onadb, 'tags', array('id' => $options['tag'])); } if (!$tag['id']) { printmsg("DEBUG => Unable to find tag ({$options['tag']})!", 3); $self['error'] = "ERROR => Unable to find tag ({$options['tag']})!"; return array(2, $self['error'] . "\n"); } // If "commit" is yes, delete the record if ($options['commit'] == 'Y') { // Check permissions if (!(auth('host_del') or auth('subnet_del'))) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } list($status, $rows) = db_delete_records($onadb, 'tags', array('id' => $tag['id'])); if ($status or !$rows) { $self['error'] = "ERROR => tag_del() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(4, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => TAG DELETED: {$tag['name']} from {$tag['type']}[{$tag['reference']}]"; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); } // Otherwise display the record that would have been deleted $text = <<<EOL Record(s) NOT DELETED (see "commit" option) Displaying record(s) that would have been deleted: NAME: {$tag['name']} TYPE: {$tag['type']} REFERENCE: {$tag['reference']} EOL; return array(6, $text); }
function domain_server_del($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.02'; printmsg("DEBUG => domain_server_del({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[commit] (default is yes) $options['commit'] = sanitize_YN($options['commit'], 'N'); // 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_del-v{$version} Removes a domain record from a DNS server Synopsis: domain_server_del [KEY=VALUE] ... Required: domain=NAME or ID domain name or ID server=NAME[.DOMAIN] or ID server name or ID Optional: commit=[Y|N] commit db transaction (no) EOM ); } if (is_numeric($options['domain'])) { $domainsearch['id'] = $options['domain']; } else { $domainsearch['name'] = strtoupper($options['domain']); } // Determine the entry itself exists list($status, $rows, $domain) = ona_get_domain_record($domainsearch); // 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_del(): Found domain, {$domain['name']}", 3); if ($options['server']) { // 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"); } } // Test that this domain is even 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 => Unable to find {$domain['name']} on server {$host['fqdn']}", 3); $self['error'] = "ERROR => Unable to find {$domain['name']} on server {$host['fqdn']}"; return array(11, $self['error'] . "\n"); } // Test that there are no NS records for this pair // ASSUMPTION: MP this will always be just one record?? // depending on how the user has their NS records set up, we may not find anything. 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']})"); // If "commit" is yes, delete the record if ($options['commit'] == 'Y') { // Check permissions if (!auth('advanced') or !authlvl($host['LVL']) or !authlvl($domain['LVL'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // delete record from domain_server_domains list($status, $rows) = db_delete_records($onadb, 'dns_server_domains', array('id' => $domainserver['id'])); if ($status) { $self['error'] = "ERROR => domain_server_del() SQL Query failed:" . $self['error']; printmsg($self['error'], 0); return array(9, $self['error'] . "\n"); } // Run the module to delete the associated NS record.. Only if we found a dns record for NS if ($dnsrec['id']) { list($status, $output) = run_module('dns_record_del', array('name' => $dnsrec['id'], 'type' => 'NS', 'commit' => 'Y')); if ($status) { $self['error'] = "ERROR => domain_server_del() NS record delete failed:" . $output; printmsg($self['error'], 0); return array(9, $self['error'] . "\n"); } else { // add the output to self error for display $add_to_error = $output; } } // Return the success notice $self['error'] = "INFO => DNS Domain/Server Pair DELETED: {$domain['name']}/{$host['fqdn']} "; printmsg($self['error'], 0); return array(0, $add_to_error . $self['error'] . "\n"); } // Otherwise display the record that would have been deleted $text = <<<EOL Record(s) NOT DELETED (see "commit" option) Displaying record(s) that would have been removed: {$domain['name']} from: {$host['fqdn']} EOL; if ($dnsrows) { $text .= " Removing related NS record, if any. Please double check your NS records for this domain.\n"; } return array(6, $text); }
function get_annotations($subject) { $out = file_get_contents($subject); $available = get_available_annotations(); $triples = array(); // match the annotations $lines = split("\n", $out); $pregs = array("/#(.*)\$/", "/\\/\\/(.*)\$/", "/\\/\\*(.*)\\*\\//"); foreach ($lines as $line) { foreach ($pregs as $preg) { if (preg_match("{$preg}", $line, $line_match)) { if (preg_match("/\\s*\n\t\t\t\t\t\t\t\t{\t\t\t\t\t\t# start matching string\n\t\t\t\t\t\t\t\t\t\\s*\n\t\t\t\t\t\t\t\t\t(\\S+\t\t\t\t# start match with name\n\t\t\t\t\t\t\t\t\t\\s*\n\t\t\t\t\t\t\t\t\t(\\(.*?\\))?\t\t# match optional argument\n\t\t\t\t\t\t\t\t\t:\n\t\t\t\t\t\t\t\t\t\\s*\n\t\t\t\t\t\t\t\t\t\\S.*\\S)\t\t\t# end match with value\n\t\t\t\t\t\t\t\t\t\\s*\n\t\t\t\t\t\t\t\t}\t\t\t\t\t\t# finish match\n\t\t\t\t\t\t\t\\s*/x", $line_match[1], $comment_match)) { $triples[] = $comment_match[1]; } } } } // Extract the annotations, adding dependencies and options. $result = array(); while (count($triples) > 0) { $triple = array_shift($triples); // match "name (options): value preg_match("/^\n\t\t\t\t\t\t(\\S+)\t\t\t\t# match name\n\t\t\t\t\t\t\\s*\n\t\t\t\t\t\t(?:\t\t\t\t# dont put this group into the result\n\t\t\t\t\t\t\t\\(\n\t\t\t\t\t\t\t\t(.*?)\t\t# match options, but not the brackets\n\t\t\t\t\t\t\t\\)\t\n\t\t\t\t\t\t)?\t\t\t\t\t# options is optional\n\t\t\t\t\t\t:\n\t\t\t\t\t\t\\s*\n\t\t\t\t\t\t(\\S.*\\S)\t\t\t# match value\n\t\t\t\t\t\t\\s*\n\t\t\t\t\t\$/x", $triple, $triple_match); $name = $triple_match[1]; $options = parse_options($triple_match[2]); $value = $triple_match[3]; phc_assert(isset($available[$name]), "Annotation {$name} not available, in {$subject}"); $available[$name]->add_value($options, $value); $result[$name] = $available[$name]; $triples = array_merge($available[$name]->get_dependencies(), $triples); } // Add default that hasnt been added. foreach ($available as $name => $annotation) { if (count($annotation->values) == 0 && $annotation->get_default_value() !== NULL) { $annotation->add_value($annotation->get_default_options(), $annotation->get_default_value()); $result[] = $annotation; } } return $result; }
function build_dhcpd_conf($options = "") { global $self; global $conf; global $onadb; // Version - UPDATE on every edit! $version = '1.10'; // Exit status of the function $exit = 0; printmsg('DEBUG => build_dhcpd_conf(' . $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['server']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console return array(1, <<<EOM build_dhcpd_conf-v{$version} Builds configuration for dhcpcd from the database Synopsis: build_dhcpd_conf [KEY=VALUE] ... Required: server=NAME[.DOMAIN] or ID Build conf by hostname or HOST_ID Optional: header_path=PATH Path to the server local header to include Notes: * Specified host must be a valid DHCP server * header_path is a file on the DHCP server. It will be defined at the very top of your configuration using the DHCP "include" directive. EOM ); } // TODO: ipv6 need to pass in if we want v4 or v6.. default to v4 for now. // looks like you cant have a mixed config // Debugging printmsg("DEBUG => Building DHCP config for: {$options['server']}", 3); // Validate that there is already a host named $options['server']. list($status, $rows, $host) = ona_find_host($options['server']); if (!$host['id']) { return array(2, "ERROR => No such host: {$options['server']}\n"); } // Now determine if that host is a valid server list($status, $dhcp_rows, $dhcp_server) = db_get_records($onadb, 'dhcp_server_subnets', array('host_id' => $host['id']), ''); list($status, $dhcpf_rows, $dhcpf_server) = db_get_records($onadb, 'dhcp_failover_groups', "primary_server_id = {$host['id']} or secondary_server_id = {$host['id']}", ''); if ($dhcp_rows == 0 and $dhcpf_rows == 0) { return array(3, "ERROR => Specified host is not a DHCP server: {$options['server']}\n"); } // Throw the host id into a self variable for later use $self['serverid'] = $host['id']; // Start an output variable with build timestamp $text .= "###### DO NOT EDIT THIS FILE ###### \n"; $text .= "# dhcpd.conf file for {$host['fqdn']} built on " . date($conf['date_format']) . "\n#\n"; $text .= "# This file is built by an automated script. Any change to this \n"; $text .= "# file will be lost at the next build.\n\n"; // setup standard include path // TODO: MP possibly put this into a configuration option like header so the user can easily change where this is. if (isset($options['header_path'])) { $text .= "include \"{$options['header_path']}\";\n"; } /////////////////////////////// Build global options ////////////////////////////////////////// list($status, $globals) = build_global($host['id']); $text .= $globals; /////////////////////////////// Failover groups ////////////////////////////////////////// // build list of failover group statements for provided server list($status, $failovergroup) = ona_dhcp_build_failover_group($host['id']); $text .= $failovergroup; /////////////////////////////// shared subnets ////////////////////////////////////////// // setup a variable to keep track of which vlan we are on $vlananchor = ''; // Loop through all of the vlan subnets and print them printmsg("DEBUG => Processing all Shared (VLAN) Subnets", 1); $i = 0; do { list($status, $rows, $vlan_subnet) = ona_get_record('vlan_id != 0 AND id IN (SELECT subnet_id FROM dhcp_server_subnets WHERE host_id = ' . $host['id'] . ' UNION SELECT subnet_id FROM dhcp_pools WHERE dhcp_failover_group_id IN (SELECT id FROM dhcp_failover_groups WHERE primary_server_id = ' . $host['id'] . ' OR secondary_server_id = ' . $host['id'] . '))', 'subnets', 'vlan_id ASC'); if ($status) { printmsg($self['error'], 0); $exit += $status; } if ($rows == 0) { printmsg("DEBUG => build_dhcpd_conf(): Found no shared subnets.", 3); break; } else { if ($i == 0) { $text .= "# --------SHARED SUBNETS (count={$rows})--------\n\n"; } } printmsg("DEBUG => Processing vlan subnet " . ($i + 1) . " of {$rows}", 3); // pull info about the vlan itself list($status, $vlanrows, $vlan) = ona_get_vlan_record(array('id' => $vlan_subnet['vlan_id'])); if ($status) { printmsg($self['error'], 0); $exit += $status; } // check to see if we have switched to a new vlan if ($vlananchor != $vlan_subnet['vlan_id']) { // if this is NOT the first loop through, close the previous shared network block if ($i >= 1) { $text .= "}\n\n"; } // print the opening statement for the shared network block and strip characters that may cause errors $text .= "shared-network " . preg_replace('/[^A-Za-z0-9_-]/', '', "{$vlan['vlan_campus_name']}-{$vlan['number']}-{$vlan['name']}") . " {\n"; } // print the subnet block for the current subnet in the loop list($status, $subnetblock) = subnet_conf($vlan_subnet, 1); if ($status) { printmsg("ERROR => subnet_conf() returned an error: vlan subnet: {$vlan_subnet['name']}", 0); $exit += $status; } else { $text .= $subnetblock; } $i++; // If the loop is at the end,and this isnt the first time we've come through the loop, print a close statement // if ($i == $rows && $vlananchor != '') {$text .= "}\n\n";} if ($i == $rows) { $text .= "}\n\n"; } // continue to update the vlan anchor $vlananchor = $vlan_subnet['vlan_id']; } while ($i < $rows); /////////////////////////////// standard subnets ////////////////////////////////////////// // Loop through all of the NON vlan subnets and print them printmsg("DEBUG => Processing all Non-Shared (Standard) Subnets", 1); // We do our own sql query here because it makes more sense than calling ona_get_record() a zillion times ;) $q = "SELECT *\n FROM subnets\n WHERE vlan_id = 0 AND\n id IN (SELECT subnet_id\n FROM dhcp_server_subnets\n WHERE host_id = {$host['id']}\n UNION\n SELECT subnet_id\n FROM dhcp_pools\n WHERE dhcp_failover_group_id IN (SELECT id\n FROM dhcp_failover_groups\n WHERE primary_server_id = {$host['id']}\n OR secondary_server_id = {$host['id']}))\n\n ORDER BY name ASC"; $rs = $onadb->Execute($q); if ($rs === false) { $self['error'] = 'ERROR => build_dhcpd_conf(): standard_subnets: SQL query failed: ' . $onadb->ErrorMsg(); printmsg($self['error'], 0); $exit += 1; } $rows = $rs->RecordCount(); if ($rows > 0) { $text .= "# --------STANDARD SUBNETS (count={$rows})--------\n"; } $i = 0; // Loop through the record set while ($std_subnet = $rs->FetchRow()) { printmsg("DEBUG => build_dhcpd_conf() Processing standard subnet " . ($i + 1) . " of {$rows}", 3); // print the subnet info for the current subnet in the loop list($status, $subnetblock) = subnet_conf($std_subnet, 0); if ($status) { printmsg("ERROR => subnet_conf() returned an error: non-vlan subnet: {$std_subnet['description']}", 0); $exit += $status; } else { $text .= $subnetblock; } $i++; } $rs->Close(); /////////////////////////////// build static hosts ////////////////////////////////////////// list($status, $hostconf) = build_hosts($host['id']); $text .= $hostconf; /////////////////////////////// Yer done, go home ////////////////////////////////////////// // Return the config file return array($exit, $text); }
function host_display($options = "") { global $conf, $self, $onadb; $text_array = array(); // Version - UPDATE on every edit! $version = '1.04'; printmsg("DEBUG => host_display({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[verbose] (default is yes) $options['verbose'] = sanitize_YN($options['verbose'], 'Y'); // Return the usage summary if we need to if ($options['help'] or !$options['host']) { // 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_display-v{$version} Displays a host record from the database Synopsis: host_display [KEY=VALUE] ... Required: host=NAME[.DOMAIN] or ID hostname or ID of the host display Optional: verbose=[yes|no] display additional info (yes) EOM ); } // Find the host (and domain) record from $options['host'] list($status, $rows, $host) = ona_find_host($options['host']); printmsg("DEBUG => Host: {$host['fqdn']}", 3); if (!$host['id']) { printmsg("DEBUG => Unknown host: {$options['host']}", 3); $self['error'] = "ERROR => Unknown host: {$options['host']}"; return array(2, $self['error'] . "\n"); } $text_array = $host; // Build text to return $text = "HOST RECORD ({$host['fqdn']})\n"; $text .= format_array($host); // If 'verbose' is enabled, grab some additional info to display if ($options['verbose'] == 'Y') { // TODO: if it is a nat interface, maybe process that IP and make it visible? // Interface record(s) $i = 0; do { list($status, $rows, $interface) = ona_get_interface_record(array('host_id' => $host['id'])); if ($rows == 0) { break; } $i++; $text .= "\nASSOCIATED INTERFACE RECORD ({$i} of {$rows})\n"; $text .= format_array($interface); $text_array['interfaces'][$i] = $interface; unset($text_array['interfaces'][$i]['host_id']); } while ($i < $rows); $text_array['interface_count'] = $rows; // Device record list($status, $rows, $device) = ona_get_device_record(array('id' => $host['device_id'])); if ($rows >= 1) { // Fill out some other device info list($status, $rows, $device_type) = ona_get_device_type_record(array('id' => $device['device_type_id'])); list($status, $rows, $role) = ona_get_role_record(array('id' => $device_type['role_id'])); list($status, $rows, $model) = ona_get_model_record(array('id' => $device_type['model_id'])); list($status, $rows, $manufacturer) = ona_get_manufacturer_record(array('id' => $model['manufacturer_id'])); $device['device_type'] = "{$manufacturer['name']}, {$model['name']} ({$role['name']})"; list($status, $rows, $location) = ona_get_location_record(array('id' => $device['location_id'])); $text_array['location'] = $location; $text_array['device'] = $device; $text .= "\nASSOCIATED DEVICE RECORD\n"; $text .= format_array($device); } // Tag records list($status, $rows, $tags) = db_get_records($onadb, 'tags', array('type' => 'host', 'reference' => $host['id'])); if ($rows) { $text .= "\nASSOCIATED TAG RECORDS\n"; foreach ($tags as $tag) { $text_array['tags'][] = $tag['name']; $text .= " {$tag['name']}\n"; } } } // Cleanup unused info unset($text_array['device_id']); unset($text_array['device']['asset_tag']); unset($text_array['device']['location_id']); unset($text_array['device']['serial_number']); // change the output format if other than default if ($options['format'] == 'json') { $text = $text_array; } if ($options['format'] == 'yaml') { $text = $text_array; } // Return the success notice return array(0, $text); }
function dns_record_display($options = "") { global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.00'; printmsg("DEBUG => dns_record_display({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[verbose] (default is yes) $options['verbose'] = sanitize_YN($options['verbose'], 'Y'); // 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 dns_record_display-v{$version} Displays a DNS record from the database Synopsis: dns_record_display [KEY=VALUE] ... Required: name=NAME[.DOMAIN] or ID hostname or ID of the dns record to display Optional: verbose=[yes|no] display additional info (yes) EOM ); } // If the name we were passed has a leading . in it then remove the dot. $options['name'] = preg_replace("/^\\./", '', $options['name']); // Find the DNS record from $options['name'] list($status, $rows, $record) = ona_find_dns_record($options['name']); printmsg("DEBUG => dns_record_del() DNS record: {$record['name']}", 3); if (!$record['id']) { printmsg("DEBUG => Unknown DNS record: {$options['name']}", 3); $self['error'] = "ERROR => Unknown DNS record: {$options['name']}"; return array(2, $self['error'] . "\n"); } // Build text to return $text = "DNS {$record['type']} RECORD ({$record['fqdn']})\n"; $text .= format_array($record); // If 'verbose' is enabled, grab some additional info to display if ($options['verbose'] == 'Y') { // PTR record(s) $i = 0; do { list($status, $rows, $ptr) = ona_get_dns_record(array('dns_id' => $record['id'], 'type' => 'PTR')); if ($rows == 0) { break; } $i++; $text .= "\nASSOCIATED PTR RECORD ({$i} of {$rows})\n"; $text .= format_array($ptr); } while ($i < $rows); // CNAME record(s) $i = 0; do { list($status, $rows, $cname) = ona_get_dns_record(array('dns_id' => $record['id'], 'type' => 'CNAME')); if ($rows == 0) { break; } $i++; $text .= "\nASSOCIATED CNAME RECORD ({$i} of {$rows})\n"; $text .= format_array($cname); } while ($i < $rows); // FIXME: MP display other types of records like NS,MX,SRV etc etc, also support dns views better } // Return the success notice return array(0, $text); }
function mysql_purge_logs($options) { global $conf, $self, $ona_db; printmsg('DEBUG => mysql_purge_logs(' . $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['slaves']) { $self['error'] = 'ERROR => Insufficient parameters'; // NOTE: Help message lines should not exceed 80 characters for proper display on a console return array(1, <<<EOM mysql_purge_logs-v{$version} Connects to a specified list of MySQL slave servers, checks where they are in reading/replicating the master server's binary logs, and deletes logs from the associated master(s) which are no longer needed by any slave system. A list of slave servers is supplied as input, and master servers are detected automatically. Synopsis: mysql_purge_logs [KEY=VALUE] Required: slaves=NAME[,NAME ...] list of slave server(s) to connect to Optional: commit=[yes|no] commit changes to database (default: no) user=NAME mysql username (default: root) password=STRING mysql password (default: blank) EOM ); } // Set default user ID, if none was provided. if (!$options['user']) { $options['user'] = '******'; } // Sanitize "options[commit]" (no is the default) $options['commit'] = sanitize_YN($options['commit'], 'N'); // Split out the list of slave servers into an array (comma-delimited). $slaves = preg_split('/,/', $options['slaves']); // Now we begin... $masters = array(); foreach ($slaves as $slave_host) { if (!$slave_host or $slave_host == "") { continue; } printmsg("DEBUG => Connect to slave host mysql://{$options['user']}:{$options['password']}@{$slave_host}", 4); $dbh = db_connect('mysql', $slave_host, $options['user'], $options['password'], 'mysql'); if (!$dbh || !$dbh->IsConnected()) { continue; } // Find out this slave's replication status. $q = "show slave status;"; $rs = $dbh->Execute($q); $array = $rs->FetchRow(); // Check if our master is listed, and if so, make sure the oldest // binary logfile (by name) is stored in the array. $matched = 0; foreach ($masters as $host => $binlog) { if ($host == $array['Master_Host'] && $binlog > $array['Master_Log_File']) { $masters['$host'] = $array['Master_Log_File']; $matched = 1; break; } } // If our master wasn't listed, then create a new entry. if ($matched == 0) { $masters[$array['Master_Host']] = $array['Master_Log_File']; } } // Now the "output" step... $retval_string = ""; $retval_errlvl = 0; foreach ($masters as $host => $binlog) { if ($options['commit'] == 'Y') { $dbh = db_connect('mysql', $host, $options['user'], $options['password'], 'mysql'); if (!$dbh || !$dbh->IsConnected()) { $self['error'] .= "ERROR => Could not connect to host '{$host}' to execute query. Skipping.\n"; $retval_errlvl = 2; continue; } } $q = "purge master logs to '{$binlog}'"; if ($options['commit'] == 'Y') { $rs = $dbh->Execute($q); $error = $dbh->ErrorMsg(); // Report any errors if ($rs === false or $error) { $self['error'] .= 'ERROR => SQL query on host {$host} failed: ' . $error . "\n"; $retval_errlvl = 2; } else { $retval_string .= "Successfully executed ({$q}) on host '{$host}'.\n"; } } else { $retval_string .= "Not commiting changes. Would have executed: ({$q}) on host '{$host}'.\n"; } } // Return our results, as success strings and (perhaps) error strings. return array($retval_errlvl, $retval_string); }
function message_add($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.00'; // Default expiration $exp_default = "+6 week"; $pri_default = 3; // Priority is one of the following: // 0 = Informational // 1 = red or high // 2 = yellow or medium // 3 = green or low printmsg("DEBUG => message_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['host'] or !$options['message'] and (!$options['expiration'] and !$options['priority'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM message_add-v{$version} Adds the provided message to the host or subnet specified Synopsis: message_add Required: host=NAME[.DOMAIN]|IP hostname or IP of the host OR subnet=NAME|IP name or IP of the subnet message="STRING" the content of the message Optional: priority=NUMBER device/model type or ID (default: {$pri_default}) expiration=DATE date to expire message (default: NOW {$exp_default}s) Notes: Priority is one of the following: 0 = blue or Informational 1 = red or high 2 = yellow or medium 3 = green or low EOM ); } // If they provided a hostname / ID let's look it up if ($options['host']) { list($status, $rows, $host) = ona_find_host($options['host']); $table_name_ref = 'hosts'; $table_id_ref = $host['id']; $desc = $host['fqdn']; } else { if ($options['subnet']) { list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); $table_name_ref = 'subnets'; $table_id_ref = $subnet['id']; $desc = $subnet['name']; } } // If we didn't get a record then exit if (!$host['id'] and !$subnet['id']) { printmsg("DEBUG => No host or subnet found!", 3); $self['error'] = "ERROR => No host or subnet found!"; return array(4, $self['error'] . "\n"); } // Set the priority $priority = array_key_exists('priority', $options) ? $options['priority'] : $pri_default; if ($priority > 3 or $priority < 0 or !is_numeric($priority)) { $self['error'] = "ERROR => Priority must be a number between 0 and 3!"; return array(4, $self['error'] . "\n"); } // Get a username or "anonymous" $username = isset($_SESSION['username']) ? $_SESSION['username'] : "******"; // Expiration date format if ($options['expiration']) { $expiration = date("Y-m-d G:i:s", strtotime($options['expiration'])); } else { $expiration = date("Y-m-d G:i:s", strtotime($exp_default)); } // TODO: there should probably be some sort of security checks on the message that is passed in. // I suspect this could be a security issue. SQL injection etc. list($status, $rows) = db_insert_record($onadb, 'messages', array('table_name_ref' => $table_name_ref, 'table_id_ref' => $table_id_ref, 'priority' => $priority, 'username' => $username, 'expiration' => $expiration, 'message_text' => $options['message'])); if ($status or !$rows) { $self['error'] = "ERROR => message_add() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } $text = "INFO => Message ADDED to: {$desc}\n"; // Return the message file return array(0, $text); }
function custom_attribute_display($options = "") { // The important globals global $conf, $self, $onadb; $text_array = array(); // Version - UPDATE on every edit! $version = '1.02'; printmsg("DEBUG => custom_attribute_display({$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['id'] and !$options['subnet'] and !$options['vlan']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM custom_attribute_display-v{$version} Display the custom attribute specified or attributes for a host Synopsis: custom_attribute_display Where: id=ID custom attribute ID OR host=ID or NAME[.DOMAIN] display custom attributes for specified host OR subnet=ID or NAME display custom attributes for specified subnet OR vlan=NAME display custom attributes for specified VLAN Optional: type=ID or NAME If you specify a type and a host or subnet you will only get back a 1 or a 0 indicating that that type is set or not set for the host or subnet EOM ); } // if a type was set, check if it is associated with the host or subnet and return 1 or 0 if ($options['type']) { $field = is_numeric($options['type']) ? 'id' : 'name'; list($status, $rows, $catype) = ona_get_custom_attribute_type_record(array($field => $options['type'])); // error if we cant find the type specified if (!$catype['id']) { $self['error'] = "ERROR => The custom attribute type specified, {$options['type']}, does not exist!"; return array(5, $self['error']); } $where['custom_attribute_type_id'] = $catype['id']; } // Search for the host first if ($options['host']) { 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']); } else { $where['table_id_ref'] = $host['id']; $where['table_name_ref'] = 'hosts'; list($status, $rows, $cas) = db_get_records($onadb, 'custom_attributes', $where); } $anchor = 'host'; $desc = $host['fqdn']; } // Search for subnet if ($options['subnet']) { list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); // Error if the record doesn't exist if (!$subnet['id']) { $self['error'] = "ERROR => The subnet specified, {$options['subnet']}, does not exist!"; return array(3, $self['error']); } else { $where['table_id_ref'] = $subnet['id']; $where['table_name_ref'] = 'subnets'; list($status, $rows, $cas) = db_get_records($onadb, 'custom_attributes', $where); } $anchor = 'subnet'; $desc = $subnet['description']; } // Search for vlan if ($options['vlan']) { list($status, $rows, $vlan) = ona_find_vlan($options['vlan']); // Error if the record doesn't exist if (!$vlan['id']) { $self['error'] = "ERROR => The VLAN specified, {$options['vlan']}, does not exist!"; return array(3, $self['error']); } else { $where['table_id_ref'] = $vlan['id']; $where['table_name_ref'] = 'vlans'; list($status, $rows, $cas) = db_get_records($onadb, 'custom_attributes', $where); } $anchor = 'vlan'; $desc = $vlan['description']; } // Now find the ID of the record, returns a specific record only if ($options['id']) { list($status, $rows, $ca) = ona_get_custom_attribute_record(array('id' => $options['id'])); if (!$ca['id']) { $self['error'] = "ERROR => The custom attribute specified, {$options['id']}, is invalid!"; return array(4, $self['error']); } $text_array = $ca; $text .= "CUSTOM ATTRIBUTE ENTRY RECORD ({$ca['id']})\n"; $text .= format_array($ca); } elseif ($options['type']) { // If we requested type, now is the time to return a response if it is found associated. if ($cas[0]) { $text .= '1'; $text_array['has_attribute'] = 'Y'; } else { $text .= '0'; $text_array['has_attribute'] = 'N'; } } else { // Build text to return $text .= strtoupper($anchor) . " CUSTOM ATTRIBUTE RECORDS ({$desc})\n"; // Display the record(s) $i = 0; do { $text .= "\nASSOCIATED CUSTOM ATTRIBUTE ENTRY RECORD ({$i} of {$rows})\n"; $text .= format_array($cas[$i]); list($status, $carows, $ca) = ona_get_custom_attribute_type_record(array('id' => $cas[$i]['custom_attribute_type_id'])); $text_array[$ca['name']] = $cas[$i]['value']; $i++; } while ($i < $rows); } // change the output format if other than default if ($options['format'] == 'json') { $text = $text_array; } if ($options['format'] == 'yaml') { $text = $text_array; } // Return the success notice return array(0, $text); }
function config_diff($options = "") { // The important globals global $conf; global $self; global $onadb; // Version - UPDATE on every edit! $version = '1.03'; printmsg('DEBUG => config_diff(' . $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'] or !$options['type']) and (!$options['ida'] or !$options['idb'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console return array(1, <<<EOM config_diff-v{$version} Displays the difference between selected archive entries Synopsis: config_diff [KEY=VALUE] ... Required: host=ID or NAME[.DOMAIN] display most recent config for specified host type=TYPE type of config to display - usually "IOS_VERSION" or "IOS_CONFIG" OR ida=ID First config ID to compare against idb idb=ID Second config ID to compare against ida Note: If you don't pass any IDs you will get the two most recent configs related to the host/type you provide. EOM ); } $text = ""; // Compare arbitrary configs based on config IDs // If we have ids, lets use those instead if ($options['ida'] and $options['idb']) { // get the two configs from the db list($status, $rows, $configs) = db_get_records($onadb, 'configurations', "id in ({$options['ida']},{$options['idb']})", 'ctime DESC', '2', ''); } else { // Get a config record if there is one $self['error'] = ""; list($status, $rows, $config) = ona_find_config($options); list($status, $rows, $configs) = db_get_records($onadb, 'configurations', array('host_id' => $config['host_id'], 'configuration_type_id' => $config['configuration_type_id']), 'ctime DESC', '2', ''); } // Error if an error was returned if ($status or $rows != 2) { if ($self['error']) { $text = $self['error'] . "\n"; } $text .= "ERROR => One or more config text entries not found!\n"; return array(2, $text); } // Get a unified text diff output $text .= text_diff($configs[1]['config_body'], $configs[0]['config_body']); // Return the success notice return array(0, $text); }
function run_module($module = '', $options = '', $transaction = 1) { global $conf, $self, $onadb; // Build the options array string from $options_string if we need to // This is only used for logging! If $options_string is an array it // is passed untouched to the module. $options_string = $options; if (is_array($options)) { $options_string = ''; $and = ''; foreach (array_keys($options) as $key) { // Quote any "special" characters in the value. // Specifically the '=' and '&' characters need to be escaped. $options[$key] = str_replace(array('=', '&'), array('\\=', '\\&'), $options[$key]); // If the key has no value or it is the javascript key, dont print it. if ($options[$key] != "" and $key != 'js') { $options_string .= "{$and}{$key}={$options[$key]}"; $and = '&'; } } } // get the options as an array so we can look for logging info $local_options = parse_options($options); // If the user passes in an option called 'module_loglevel' then use it as the run module output level // otherwise default it to 1 so it will print out as normal. $log_level = 1; if ($local_options['module_loglevel']) { $log_level = $local_options['module_loglevel']; } // Remove config info as it can be huge and could have sensitive info in it. // This could cause issues since I"m doing & as an anchor at the end. see how it goes. // The module that is called could also display this information depending on debug level $options_string = preg_replace("/config=.*&/", '', $options_string); printmsg("INFO => Running module: {$module} options: {$options_string}", $log_level); // Load the module if (load_module($module)) { return array(1, $self['error'] . "\n"); } // Start an DB transaction (If the database supports it) if ($transaction) { $has_trans = $onadb->BeginTrans(); } if (!$has_trans) { printmsg("WARNING => Transactions support not available on this database, this can cause problems!", 1); } // If begintrans worked and we support transactions, do the smarter "starttrans" function if ($has_trans) { printmsg("DEBUG => Commiting transaction", 2); $onadb->StartTrans(); } // Start a timer so we can display moudle run time if debugging is enabled $start_time = microtime_float(); // Run the function list($status, $output) = $module($options); // Stop the timer, and display how long it took $stop_time = microtime_float(); printmsg("DEBUG => [Module_runtime] " . round($stop_time - $start_time, 2) . " seconds -- [Total_SQL_Queries] " . $self['db_get_record_count'] . " -- [Module_exit_code] {$status}", 1); // Either commit, or roll back the transaction if ($transaction and $has_trans) { if ($status != 0) { printmsg("INFO => There was a module error, marking transaction for a Rollback!", 1); //$onadb->RollbackTrans(); $onadb->FailTrans(); } } if ($has_trans) { // If there was any sort of failure, make sure the status has incremented, this catches sub module output errors; if ($onadb->HasFailedTrans()) { $status = $status + 1; } // If the user passed the rollback flag then dont commit the transaction // FIXME: not complete or tested.. it would be nice to have an ability for the user to pass // a rollback flag to force the transaction to rollback.. good for testing adds/modify. // The problem is sub modules will fire and then the whole thing stops so you wont see/test the full operation. // if ($local_options['rollback']) { // printmsg("INFO => The user requested to mark the transaction for a rollback, no changes made.", 0); // $output .= "INFO => The user requested to mark the transaction for a rollback, no changes made.\n"; // $status = $status + 1; // } printmsg("DEBUG => Commiting transaction", 2); $onadb->CompleteTrans(); } // Return the module's output return array($status, $output); }
function block_display($options = "") { global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.00'; printmsg("DEBUG => block_display({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[verbose] (default is yes) $options['verbose'] = sanitize_YN($options['verbose'], 'Y'); // Return the usage summary if we need to if ($options['help'] or !$options['block']) { // 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_display-v{$version} Displays a block record from the database Synopsis: block_display [KEY=VALUE] ... Required: block=NAME or ID Block name or ID of the block display Optional: verbose=[yes|no] Display additional info (DEFAULT: yes) EOM ); } // The formatting rule on block names is all upper and trim it $options['block'] = trim($options['block']); $options['block'] = preg_replace('/\\s+/', '-', $options['block']); $options['block'] = strtoupper($options['block']); // If the block provided is numeric, check to see if it's an block if (is_numeric($options['block'])) { // See if it's an block_id list($status, $rows, $block) = ona_get_block_record(array('id' => $options['block'])); if (!$block['id']) { printmsg("DEBUG => Unable to find block using the ID {$options['block']}!", 3); $self['error'] = "ERROR => Unable to find block using the ID {$options['block']}!"; return array(2, $self['error'] . "\n"); } } else { list($status, $rows, $block) = ona_get_block_record(array('name' => $options['block'])); if (!$block['id']) { $self['error'] = "ERROR => Unable to find block using the name {$options['block']}!"; printmsg("DEBUG => Unable to find block using the name {$options['block']}!", 3); return array(2, $self['error'] . "\n"); } } printmsg("DEBUG => Found block: {$block['name']}", 3); // Build text to return $text = "BLOCK RECORD\n"; $text .= format_array($block); // If 'verbose' is enabled, grab some additional info to display if ($options['verbose'] == 'Y') { $where .= " ip_addr >= " . $block['ip_addr_start'] . " AND ip_addr <= " . $block['ip_addr_end']; list($status, $netrows, $nets) = db_get_records($onadb, 'subnets', $where, "ip_addr"); // subnet record(s) $i = 0; foreach ($nets as $record) { list($status, $rows, $subnet) = ona_get_subnet_record(array('id' => $record['id'])); if ($rows == 0) { break; } $i++; $text .= "\nASSOCIATED SUBNET RECORD ({$i} of {$netrows})\n"; $text .= format_array($subnet); } } // Return the success notice return array(0, $text); }
function cws_shortcode_html_gen($options_array, $id, $value, $id_postfix = '', $ispopup = true, $prefix = 'mb') { $output = ''; if (@$options_array[$id]) { $output .= '<table class="mb-table">'; if ($ispopup) { $output .= '<th colspan=2 class="shortcode-name">Shortcode: <span>' . $id . '</span></th>'; } $output .= parse_options($options_array[$id]['options'], $value, $prefix, $id_postfix, '', true); $output .= '</table>'; } return $output; }