array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w') ); $pipes = array(); $cwd = '/tmp'; $env = array(); $proc = proc_open($g_nsupdate, $desc, $pipes, $cwd, $env); if (!is_resource($proc)) { Error("Unable to execute " . $g_nsupdate); } Debug("proc_open(" . $g_nsupdate . ', $desc, $pipes, $cwd, $env)'); Debug("Sending this to nsupdate:\n" . $input); fwrite($pipes[0], $input); $output = stream_get_contents($pipes[1]); $errors = stream_get_contents($pipes[2]); fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); $ret = proc_close($proc); if ($ret > 0) { Error($g_nsupdate . " return code " . $ret . ": " . $errors); } return $output; } function dig($parameters) { global $g_dig; // Replace newlines for security reasons $parameters = str_replace("\n", "", $parameters); if (!ShellEscapeCheck($parameters)) die('FATAL: Invalid shell parameters: ' . $parameters); Debug("shell_exec: " . $g_dig . " " . $parameters); return shell_exec($g_dig . " " . $parameters); } // Convert standard DNS list of records as returned by transfer to PHP array function raw_zone_to_array($data) { $records = array(); $data = explode("\n", $data); foreach ($data as $line) { if (psf_string_startsWith($line, ";")) continue; // This is a little bit hard-core, we need to parse output from dig, which is terrible // In past we did some magic by simply replacing all tabs and spaces to split it, but that doesn't work // for some special TXT records // For example: // 2 tabs tab double space // v v v // example.org. 600 IN TXT "v=spf1 a mx include:_spf.example.org ip4:124.6.178.206 ~all" // // keep in mind that dig is randomly using tabs as separators and randomly spaces // // So there are two easy ways of this mess // 1) we use regular expressions and pray a lot (we use this one) // 2) we simply walk through out the whole string, that's the correct way, but this is actually CPU intensive, // so we might want to implement this into some kind of C library I guess // Get rid of empty lines if (strlen(str_replace(" ", "", $line)) == 0) continue; $records[] = preg_split('/[\t\s]/', $line, 5, PREG_SPLIT_NO_EMPTY); } return $records; } function get_zone_data($zone) { global $g_domains; $zone_servers = $g_domains[$zone]; $data = dig("axfr " . $zone . " @" . $zone_servers["transfer_server"]); return raw_zone_to_array($data); } function get_zone_soa($zone) { global $g_domains; $zone_servers = $g_domains[$zone]; $data = dig("SOA " . $zone . " @" . $zone_servers["transfer_server"]); return raw_zone_to_array($data); } function get_records_from_zone($fqdn, $type, $zone) { global $g_domains; $zone_servers = $g_domains[$zone]; $data = dig('+nocomments +noauthority +noadditional ' . $type . " '" . $fqdn . "' @" . $zone_servers["transfer_server"]); return raw_zone_to_array($data); }