ona  18.1.1
About: OpenNetAdmin provides a database managed inventory of your IP network (with Web and CLI interface).
  Fossies Dox: ona-18.1.1.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

functions_general.inc.php
Go to the documentation of this file.
1 <?php
2 // DON'T put whitespace at the beginning or end of this file!!!
3 
4 
5 // Debugging: lets print what's in $_REQUEST
6 if ( 6 <= $conf['debug'] ) {
7  printmsg("Get/Post vars:", 6);
8  foreach (array_keys($_REQUEST) as $key) printmsg("Name: $key Value: $_REQUEST[$key]", 6);
9 }
10 
11 // MP: moved this stuff to config.inc.php
12 
13 // Include the basic database functions
14 //require_once($conf['inc_functions_db']);
15 
16 // (Re)Connect to the DB now.
17 //global $onadb;
18 //$onadb = db_pconnect('mysqlt', $conf['mysql_context']);
19 
20 // Include functions that replace the default session handler with one that uses MySQL as a backend
21 //require_once($conf['inc_db_sessions']);
22 
23 // Include the GUI functions
24 //require_once($conf['inc_functions_gui']);
25 
26 // Start the session handler (this calls a function defined below in this file)
27 //startSession();
28 
29 
30 // Include the GUI functions
31 //require_once($base.'/include/functions_auth.inc.php');
32 
33 
34 
35 /***************/
36 /* Functions */
37 /***************/
38 
40 // Function: printmsg (string $msg, int $level)
41 //
42 // $msg = Message you would like to display
43 // $level = debug level that has to be reached before this message would be displayed.
44 //
45 // Prints a message if $level is less than or equal to global debug value
46 //
48 function printmsg($msg="",$debugLevel=0) {
49  global $conf, $self;
50 
51  if ($debugLevel <= $conf['debug'] and isset($msg)) {
52 
53  // Get a username or "anonymous"
54  if (isset($_SESSION['ona']['auth']['user']['username']))
55  $username = $_SESSION['ona']['auth']['user']['username'];
56  else
57  $username = "anonymous";
58 
59  // Print to a log file if needed
60  if ($conf['logfile'])
61  ona_logmsg($msg);
62 
63  // log level 0 entries to database table
64  if ($conf['log_to_db'] and $debugLevel == 0) {
65  global $onadb;
66  // MP TODO: log using tia64n
67  list($status, $rows) = db_insert_record($onadb, 'ona_logs', array('username' => $username, 'remote_addr' => $_SERVER['REMOTE_ADDR'], 'message' => $msg,'context_name' => $self['context_name']));
68  }
69 
70  // Print to syslogd if needed
71  if ($conf['syslog']) {
72  // MP: fix this up so it uses openlog and allows the user to set the facility?
73  syslog(LOG_INFO, "ONA {$username}@{$_SERVER['REMOTE_ADDR']}: [{$self['context_name']}] $msg");
74  }
75 
76  // Print to stdout (i.e. the web page) if needed
77  if ($conf['stdout']) {
78  if ($self['nohtml'] == 1)
79  echo $msg . "\n";
80  else {
81  $msg = htmlentities($msg, ENT_QUOTES, $conf['php_charset']);
82  echo "<b>[$debugLevel]</b>:<font style=\"
83  font-size:12px;
84  color:crimson;
85  background-color:yellow;
86  \">
87  $msg
88  </font><b></b><br>\n";
89  }
90  }
91  }
92 }
93 
94 
95 
96 
97 
98 
99 
100 
101 
103 // Function: logmsg(string $message, string $logfile)
104 //
105 // Write $message into $logfile.
106 // $logfile is optional and will use a default specified below.
107 //
108 // $message = the message to be logged to disk
109 // $logfile = the file we should log it to
110 //
111 //
113 function ona_logmsg($message, $logfile="") {
114  global $conf, $self;
115 
116  // Do a little input validation
117  if (!isset($message) or $message == "") {
118  return("Can't log a blank line you idiot!");
119  }
120 
121  // Get logfile from $conf if it wasn't specified
122  if (!$logfile) {
123  $logfile = $conf['logfile'];
124  }
125 
126  // Open the file
127  $file = fopen($logfile, "a+");
128  if (!$file) {
129  return(1);
130  }
131 
132  // Get the hostname (and a few other things we don't use)
133  // After this we can reference $uname['nodename'] which will have our hostname
134  $uname['nodename'] = "UNKNOWN_SVR_NAME";
135  if (function_exists('posix_uname')) {
136  $uname = posix_uname();
137  }
138 
139  // Get a username or "anonymous"
140  if (isset($_SESSION['ona']['auth']['user']['username'])) {
141  $username = $_SESSION['ona']['auth']['user']['username'];
142  }
143  else {
144  $username = "anonymous";
145  }
146 
147  // Build the exact line we want to write to the file
148  $logdata = date("M j G:i:s ") . "{$uname['nodename']} {$username}@{$_SERVER['REMOTE_ADDR']}: [{$self['context_name']}] {$message}\n";
149 
150  // Write the line to the file
151  if (!fwrite($file, $logdata)) {
152  return(1);
153  }
154 
155  // Close the file
156  fclose($file);
157 
158  // Return 0 for no errors, or >0 if there was any errors
159  return(0);
160 
161 }
162 
163 
164 
165 
166 
167 
168 
169 
170 
171 
172 
173 
175 // Function: strsize (string $string)
176 //
177 // Returns a nicely formatted string of the size of the string $string
178 //
180 function strsize($string) {
181  $tmp = array("B", "KB", "MB", "GB", "TB", "PB");
182 
183  $pos = 0;
184  $size = strlen($string);
185  while ($size >= 1024) {
186  $size /= 1024;
187  $pos++;
188  }
189 
190  return round($size,2)." ".$tmp[$pos];
191 }
192 
193 
194 
195 
196 
197 
198 
199 
201 // Function: truncate (string $msg, int length)
202 //
203 // $msg = Message you would like to (possibly) truncate
204 // $length = Max length you want $msg to be
205 //
206 // Returns $msg with a maximum length of $length.
207 //
209 function truncate($msg="",$length=0) {
210  global $conf;
211  if ($length > 0)
212  $msg = (mb_strlen($msg) < $length) ? $msg : mb_substr($msg,0,$length - 3) . "...";
213 
214  return($msg);
215 }
216 
217 
218 
219 
220 
221 
222 
223 
225 // Function: fix_input(string $in)
226 //
227 // Basically does a "strip_slashes()" if magic quotes are turned on.
228 // Returns the fixed input.
230 function fix_input($string) {
231  // Stripslashes from $_REQUEST input if magic_quotes is enabled -
232  // we quote everything properly in this code :)
233  if (get_magic_quotes_gpc())
234  $string = stripslashes($string);
235 
236  return($string);
237 }
238 
239 
240 
241 
242 
243 
244 
245 
252 function cleanText($text){
253  $text = preg_replace("/(\015\012)|(\015)/","\012",$text);
254  return $text;
255 }
256 
257 
258 
259 
260 
261 
262 
263 
267 function microtime_float() {
268  list($usec, $sec) = explode(" ", microtime());
269  return ((float)$usec + (float)$sec);
270 }
271 
272 
273 
274 
275 
276 
277 
278 
279 
281 // Function: ip_mangle($ip, [$format])
282 //
283 // $input is the ip address in either numeric or dotted format
284 // $format is the format the ip address will be returned in:
285 // 1 or numeric: 170666057
286 // 2 or dotted: 10.44.40.73
287 // 3 or cidr: 24 (or /24) (for netmasks only)
288 // 4 or binary: 1010101010101010101010101010101010101010
289 //
290 // Options 5,6,7 are only supported by GMP module
291 // 5 or bin128: 1010101010101010101010101010101010101010... (128 bits)
292 // 6 or ipv6: FE80:0000:0000:0000:0202:B3FF:FE1E:8329
293 // 7 or ipv6gz: FE80::202:B3FF:FE1E:8329 or
294 // ::C000:280 or
295 // ::ffff:C000:280
296 //
297 //
298 //
299 // 8 or flip: 10.1.2.3 changes to 3.2.1.10
300 //
301 //
302 // Wrapper around the two versions of ip_mangle. one with GMP one without.
303 // The non GMP version is not ipv6 compatible
304 //
305 // Example:
306 // print "IP is: " . ip_mangle(170666057)
308 function ip_mangle($ip="", $format="default") {
309  global $self;
310 
311 
312  if (function_exists('gmp_init')) {
313  return(ip_mangle_gmp($ip, $format));
314  }
315  else {
316  printmsg("INFO => Falling back to non GMP enabled ip_mangle function",5);
317  return(ip_mangle_no_gmp($ip, $format));
318  }
319 }
320 
321 
322 
323 
324 
325 
326 
327 
328 
329 
330 
332 // Function: ip_mangle($ip, [$format])
333 //
334 // $input is the ip address in either numeric or dotted format
335 // $format is the format the ip address will be returned in:
336 // 1 or numeric: 170666057
337 // 2 or dotted: 10.44.40.73
338 // 3 or cidr: 24 (or /24) (for netmasks only)
339 // 4 or binary: 1010101010101010101010101010101010101010
340 // 8 or flip: 10.1.2.3 changes to 3.2.1.10
341 //
342 // Formats the input IP address into the format specified. When a
343 // format is not specified dotted format is returned unless you
344 // supply a dotted input, in which case numeric format (1) is returned.
345 // Returns -1 on any error and stores a message in $self['error']
346 //
347 // Example:
348 // print "IP is: " . ip_mangle(170666057)
350 function ip_mangle_no_gmp($ip="", $format="default") {
351  global $self;
352 
353  // Is input in dotted format (2)?
354  if (preg_match('/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/', $ip)) {
355  $ip = ip2long($ip);
356  if ($format == "default") { $format = 1; }
357  }
358 
359  // Is it in CIDR format (3)?
360  else if (preg_match('/^\/?(\d{1,2})$/', $ip, $matches)) {
361  if (!($matches[1] >= 0 && $matches[1] <= 32)) {
362  $self['error'] = "ERROR => Invalid CIDR mask";
363  return(-1);
364  }
365  // So create a binary string of 1's and 0's and convert it to an int
366  $ip = bindec(str_pad(str_pad("", $matches[1], "1"), 32, "0"));
367  if ($format == "default") { $format = 2; }
368  }
369 
370  // Is it in binary format (4)?
371  else if (preg_match('/^[01]{32}$/', $ip)) {
372  $ip = bindec($ip);
373  if ($format == "default") { $format = 2; }
374  }
375 
376  // If it has a non-digit character, it's invalid.
377  else if (preg_match('/\D/', $ip)) {
378  $ip = -1;
379  }
380 
381  // Then input must be in numeric format (1)
382  else {
383  // We flip it to dotted and back again to make sure it's a valid address
384  $ip = long2ip($ip);
385  $ip = ip2long($ip);
386  if ($format == "default") { $format = 2; }
387  }
388 
389 
390  // If the address wasn't valid return an error
391  if ($ip == -1) {
392  $self['error'] = "ERROR => Invalid IP address";
393  return(-1);
394  }
395 
396 
397  // Is output format 1 (numeric)?
398  if ($format == 1 or $format == 'numeric') {
399  return(sprintf("%u", $ip));
400  }
401 
402  // Is output format 2 (dotted)?
403  else if ($format == 2 or $format == 'dotted') {
404  return(long2ip($ip));
405  }
406 
407  // Is output format 3 (CIDR)?
408  else if ($format == 3 or $format == 'cidr') {
409  // Make sure the address is a valid mask - convert it to 1's and 0's,
410  // then make sure it's all 1's followed by all 0's.
411  $binary = str_pad(decbin($ip), 32, "0", STR_PAD_LEFT);
412  if (!(preg_match('/^1+0*$/', $binary))) {
413  $self['error'] = "ERROR => IP address specified is not a valid netmask";
414  return(-1);
415  }
416  // Return the number of 1's at the beginning of the binary representation of $ip
417  return(strlen(rtrim($binary,"0")));
418  }
419 
420  // Is output format 4 (binary string)?
421  else if ($format == 4 or $format == 'binary') {
422  // Convert the integer to it's 32 bit binary representation
423  return(str_pad(decbin($ip), 32, "0", STR_PAD_LEFT));
424  }
425 
426  // Is output format 8 (flipped IP string)?
427  else if ($format == 8 or $format == 'flip') {
428  $octet = explode('.',long2ip(sprintf("%s", $ip)));
429  return(sprintf("%s.%s.%s.%s",$octet[3],$octet[2],$octet[1],$octet[0]));
430  }
431 
432  else {
433  $self['error'] = "ERROR => ip_mangle() Invalid IP address format specified!";
434  return(-1);
435  }
436 
437 }
438 
439 
440 
441 
442 
443 
445 // Function: ip_mangle($ip, [$format])
446 //
447 // $input is the ip address in either numeric or dotted format
448 // $format is the format the ip address will be returned in:
449 // 1 or numeric: 170666057
450 // 2 or dotted: 10.44.40.73
451 // 3 or cidr: 24 (or /24) (for netmasks only)
452 // 4 or binary: 1010101010101010101010101010101010101010 (32 bits)
453 // 5 or bin128: 1010101010101010101010101010101010101010... (128 bits)
454 // 6 or ipv6: FE80:0000:0000:0000:0202:B3FF:FE1E:8329
455 // 7 or ipv6gz: FE80::202:B3FF:FE1E:8329 or
456 // ::C000:280 or
457 // ::ffff:C000:280
458 // 8 or flip: 10.1.2.3 changes to 3.2.1.10
459 //
460 // (currently unsupported for input or output) 0:0:0:0:0:0:192.0.2.128
461 // (currently unsupported for input or output) ::ffff:192.0.2.128
462 // (currently unsupported for input or output) ::192.0.2.128
463 //
464 // Formats the input IP address into the format specified. When a
465 // format is not specified dotted format is returned unless you
466 // supply a dotted input, in which case numeric format (1) is returned.
467 // Returns -1 on any error and stores a message in $self['error']
468 //
469 // Example:
470 // print "IP is: " . ip_mangle(170666057)
472 function ip_mangle_gmp($ip="", $format="default") {
473  // is_ipv4 returns TRUE if $inp can be represented as an IPv4 address
474  // FALSE if $inp cannot be represented as an IPv4 address (e.g. IPv6)
475  // Note: $inp is a 'gmp' resource, created by 'gmp_init()'.
476  if(!function_exists("is_ipv4")) {
477  function is_ipv4($inp) {
478  if(gmp_cmp(gmp_init("0xffffffff"), $inp) >= 0)
479  return TRUE;
480  return FALSE;
481  }
482  }
483 
484  // Split a string into an array, each element of length $length characters.
485  // This function doesn't exist in PHP < 5.0.0.
486  if (!function_exists("str_split")) {
487  function str_split($str,$length = 1) {
488  if ($length < 1) return false;
489  $strlen = strlen($str);
490  $ret = array();
491  for ($i = 0; $i < $strlen; $i += $length) {
492  $ret[] = substr($str,$i,$length);
493  }
494  return $ret;
495  }
496  }
497 
498  // Converts an ipv6 formatted input string to a GMP resource
499  if (!function_exists("ip2gmp6")) {
500  function ip2gmp6($ip) {
501  // Expand '::' to zero stanzas
502  if (substr_count($ip, '::'))
503  $ip = str_replace('::',
504  str_repeat(':0000', 8-substr_count($ip, ':')) . ':', $ip);
505  $ip = explode(':', $ip) ;
506  $r_ip = '';
507  // Insert any missing leading zeros in each stanza.
508  foreach ($ip as $v)
509  $r_ip .= str_pad($v, 4, 0, STR_PAD_LEFT) ;
510  return (gmp_init($r_ip, 16));
511  }
512  }
513 
514  // When given an uncompressed IPv6 address string of the form
515  // 0000:1111:2222:3333:4444:5555:6666:7777:8888, this
516  // will return a 'compressed' IPv6 address string. It replaces the
517  // longest consecutive sequence of "0000" stanzas with double
518  // colons ("::") and strips any leading zeros in each stanza.
519  //
520  // For example, input string fe80:0000:0000:0000:00ff:0000:a033:05b7
521  // will be output as string fe80::ff:0:a033:5b7.
522  if (!function_exists("ipv6gz")) {
523  function ipv6gz($ip) {
524  $e = explode(':', $ip);
525  $e[] = "XXXX"; // add a sentinel value
526  $zeros = array("0000");
527  $result = array_intersect ($e, $zeros );
528  // $result now contains only the non-zero stanzas from $ip
529  if (sizeof($result) > 0) {
530  // Find the longest sequence of zero stanzas
531  $begin = $start = ""; $len = 0;
532  foreach($e as $key=>$val) {
533  if($val === "0000") {
534  if($begin === "") {
535  $begin = $key;
536  if ($start === "")
537  $start = $begin;
538  }
539  } else {
540  if($begin !== "") {
541  if($key-$begin > $len) {
542  $len = $key-$begin;
543  $start = $begin;
544  }
545  $begin = "";
546  }
547  }
548  }
549  array_pop($e); // remove the sentinel value
550 
551  // Replace that sequence with '::', strip leading zeros, etc
552  $newip=array();
553  foreach($e as $key=>$val) {
554  if($start !== "" && $key > $start && $key < $start+$len) continue;
555  if($start !== "" && $key === $start)
556  $val = '';
557  else
558  $val = base_convert($val, 16, 16);
559  $newip[] = $val;
560  }
561  // Corner cases: (1) If the final stanza is compressed, add one more
562  // empty array element, so we will end with two colons, not just one.
563  // (2) If the whole string was zeros, then add another empty element.
564  // (3) If the beginning stanza is compressed, prepend an empty array
565  // element, _unless_ cases (1) and (2) were both true.
566  if($start+$len == 8) { $newip[] = ''; }
567  if($len == 8) { $newip[] = ''; }
568  if($start == 0 && $len < 8) { array_unshift($newip, ''); }
569  $ip = implode(':', $newip);
570  }
571  return $ip;
572  }
573  }
574 
575  global $self;
576 
577  // Is input in IPv4 dotted format (2)?
578  if (preg_match('/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/', $ip)) {
579  if($ip != long2ip(ip2long($ip))) {
580  $self['error'] = "ERROR => Invalid IPv4 address";
581  return(-1);
582  }
583  $ip = gmp_init(sprintf("%u", ip2long($ip)), 10);
584  if ($format == "default") { $format = "numeric"; }
585  }
586 
587  // Is it in IPv4/IPv6 CIDR format (3)?
588  else if (preg_match('/^\/?(\d{1,3})$/', $ip, $matches)) {
589  if (!($matches[1] >= 0 && $matches[1] <= 128)) {
590  $self['error'] = "ERROR => Invalid CIDR mask";
591  return(-1);
592  }
593 
594  // So create a binary string of 1's and 0's and convert it to an int
595  if($matches[1] <= 32) { $cidr_bits = 32; }
596  else { $cidr_bits = 128; }
597  $ip = gmp_init(str_pad(str_pad("", $matches[1], "1"), $cidr_bits, "0"), 2);
598  if ($format == "default") {
599  // Default to IPv6 output if the input was IPv6, IPv4 otherwise
600  if (is_ipv4($ip))
601  $format = "dotted";
602  else
603  $format = "ipv6";
604  }
605  }
606 
607  // Is it in 32-bit binary format (4)?
608  else if (preg_match('/^[01]{32}$/', $ip)) {
609  //$ip = bindec($ip);
610  $ip = gmp_init(strval($ip), 2);
611  if ($format == "default") { $format = "dotted"; }
612  }
613 
614  // Is it in 128-bit binary format (5)?
615  else if (preg_match('/^[01]{128}$/', $ip)) {
616  $ip = gmp_init(strval($ip), 2);
617  if ($format == "default") { $format = "ipv6"; }
618  }
619 
620  // Is it in ipv6 format (6)?
621  // This matches the 'full' uncompressed IPv6 format, the format without
622  // leading zeros in each stanza, and also 'compressed' IPv6 format, which
623  // substitutes '::' for multiple zero stanzas.
624  else if ( (substr_count($ip, '::') == 1 && substr_count($ip, ':::') == 0 &&
625  preg_match('/^:|([0-9A-F]{1,4}:){0,7}:|(:[0-9A-F]{1,4}){0,7}$/i', $ip)) or
626  preg_match('/^([0-9A-F]{1,4}:){7}([0-9A-F]{1,4})$/i', $ip)) {
627  $ip = ip2gmp6($ip);
628  if ($format == "default") { $format = "numeric"; }
629  }
630 
631  // If at this point, it has a non-digit character, it's invalid.
632  else if (preg_match('/\D/', $ip)) {
633  $ip = -1;
634  }
635 
636  // If we get here, then the input must be in numeric format (1)
637  else {
638  $ip = gmp_init(strval($ip), 10);
639  if ($format == "default") {
640  if(is_ipv4($ip))
641  $format = "dotted";
642  else
643  $format = "ipv6";
644  }
645  }
646 
647 
648  // If the address wasn't valid return an error --
649  // check for out-of-range values (< 0 or > 2**128)
650  if (gmp_cmp(gmp_init(-1), $ip) >= 0 or
651  gmp_cmp(gmp_pow("2", 128), $ip) <= 0) {
652  $self['error'] = "ERROR => Invalid IP address";
653  return(-1);
654  }
655 
656 
657  // Is output format 1 (numeric)?
658  if ($format == 1 or $format == 'numeric')
659  //return(sprintf("%u", $ip));
660  return(sprintf("%s", gmp_strval($ip, 10)));
661 
662  // Is output format 2 (dotted)?
663  else if ($format == 2 or $format == 'dotted') {
664  if(!is_ipv4($ip)) {
665  return(ipv6gz(implode(":", str_split(str_pad(gmp_strval($ip, 16), 32, "0", STR_PAD_LEFT), 4))));
666  // $self['error'] = "ERROR => Invalid IPv4 address";
667  // return(-1);
668  }
669  return(long2ip(sprintf("%s", gmp_strval($ip))));
670  }
671 
672  // Is output format 3 (CIDR)?
673  else if ($format == 3 or $format == 'cidr') {
674  // Make sure the address is a valid mask - convert it to 1's and 0's,
675  // then make sure it's all 1's followed by all 0's.
676  if(is_ipv4($ip))
677  $cidr_bits = 32;
678  else
679  $cidr_bits = 128;
680  $binary = str_pad(gmp_strval($ip, 2), $cidr_bits, "0", STR_PAD_LEFT);
681  if (!(preg_match('/^1+0*$/', $binary))) {
682  $self['error'] = "ERROR => IP address specified is not a valid netmask";
683  return(-1);
684  }
685  // Return the number of 1's at the beginning of the binary representation of $ip
686  return(strlen(rtrim(gmp_strval($ip, 2), "0")));
687 
688  }
689 
690  // Is output format 4 (32-bit binary string)?
691  else if ($format == 4 or $format == 'binary') {
692  // Convert the integer to its 32-bit binary representation
693  return(str_pad(gmp_strval($ip, 2), 32, "0", STR_PAD_LEFT));
694  }
695 
696  // Is output format 5 (128-bit binary string)?
697  else if ($format == 5 or $format == 'bin128') {
698  // Convert the number to its 128-bit binary representation
699  return(str_pad(gmp_strval($ip, 2), 128, "0", STR_PAD_LEFT));
700  }
701 
702  // Is output format 6 (uncompressed IPv6 string)?
703  else if ($format == 6 or $format == 'ipv6') {
704  // Convert the number to 8x 16-bit hexidecimal stanzas.
705  return(implode(":", str_split(str_pad(gmp_strval($ip, 16), 32, "0", STR_PAD_LEFT), 4)));
706  }
707 
708  // Is output format 7 (compressed IPv6 string)?
709  else if ($format == 7 or $format == 'ipv6gz') {
710  return(ipv6gz(implode(":", str_split(str_pad(gmp_strval($ip, 16), 32, "0", STR_PAD_LEFT), 4))));
711  }
712 
713  // Is output format 8 (flipped IP string)?
714  else if ($format == 8 or $format == 'flip') {
715  if(!is_ipv4($ip)) {
716  // Turn it into a ip6.arpa PTR record format with nibbles and all!
717  return(strrev(implode(".", str_split(str_pad(gmp_strval($ip, 16), 32, "0", STR_PAD_LEFT), 1))));
718  //$self['error'] = "ERROR => Invalid IPv4 address";
719  //return(-1);
720  }
721  $octet = explode('.',long2ip(sprintf("%s", gmp_strval($ip))));
722  return(sprintf("%s.%s.%s.%s",$octet[3],$octet[2],$octet[1],$octet[0]));
723  }
724 
725  else {
726  $self['error'] = "ERROR => ip_mangle() Invalid IP address format specified!";
727  return(-1);
728  }
729 }
730 
731 
732 
733 
734 
735 
736 
737 
738 
740 // Function: ipcalc_info($ip,$mask)
741 //
742 // Gathers various bits of IP info for use in an ipcalc tools/modules
743 // Returns an array of those bits of info.
744 //
745 // Example:
746 // $level = ipcalc_info($ip,$mask)
748 function ipcalc_info($ip='', $mask='') {
749  global $conf, $self;
750 
751 
752 // MP: fix the fact that I"m not testing for the GMP module.. it will fail for ipv6 stuff
753  $retarray = array();
754 
755  $retarray['in_ip'] = $ip;
756  $retarray['in_mask'] = $mask;
757  $retarray['mask_cidr'] = ip_mangle($retarray['in_mask'], 'cidr');
758 
759  // Process the IP address
760  $retarray['ip_dotted'] = ip_mangle($retarray['in_ip'], dotted);
761  $retarray['ip_numeric'] = ip_mangle($retarray['in_ip'], numeric);
762  $retarray['ip_binary'] = ip_mangle($retarray['in_ip'], binary);
763  $retarray['ip_bin128'] = ip_mangle($retarray['in_ip'], bin128);
764  $retarray['ip_ipv6'] = ip_mangle($retarray['in_ip'], ipv6);
765  $retarray['ip_ipv6gz'] = ip_mangle($retarray['in_ip'], ipv6gz);
766  $retarray['ip_flip'] = ip_mangle($retarray['in_ip'], flip);
767 
768  // Process the mask
769  $retarray['mask_dotted'] = ip_mangle($retarray['in_mask'], dotted);
770  $retarray['mask_numeric'] = ip_mangle($retarray['in_mask'], numeric);
771  $retarray['mask_binary'] = ip_mangle($retarray['in_mask'], binary);
772  $retarray['mask_bin128'] = ip_mangle($retarray['in_mask'], bin128);
773  $retarray['mask_ipv6'] = ip_mangle($retarray['in_mask'], ipv6);
774  $retarray['mask_ipv6gz'] = ip_mangle($retarray['in_mask'], ipv6gz);
775  $retarray['mask_flip'] = ip_mangle($retarray['in_mask'], flip);
776 
777 
778  // Invert the binary mask
779  $inverted = str_replace("0", "x", ip_mangle($retarray['in_mask'], binary));
780  $inverted = str_replace("1", "0", $inverted);
781  $inverted = str_replace("x", "1", $inverted);
782  $retarray['mask_bin_invert'] = $inverted;
783  $retarray['mask_dotted_invert'] = ip_mangle($inverted, dotted);
784 
785 
786  // Check boundaries
787  // This section checks that the IP address and mask are valid together.
788  // if the IP address does not fall on a proper boundary based on the provided mask
789  // we will return the 'truenet' that it would fall into.
790  $retarray['netboundary'] = 1;
791 
792  if(is_ipv4($retarray['ip_numeric'])) {
793  // echo "ipv4";
794  $padding = 32;
795  $fmt = 'dotted';
796  $ip1 = ip_mangle($retarray['ip_numeric'], 'binary');
797  $ip2 = str_pad(substr($ip1, 0, $retarray['mask_cidr']), $padding, '0');
798  $total = (0xffffffff - $retarray['mask_numeric']) + 1;
799  $usable = $total - 2;
800  $lastip = ip_mangle($ip2, numeric) - 1 + $total;
801  $retarray['ip_last'] = ip_mangle($lastip, 'dotted');
802  } else {
803  // echo "ipv6";
804  $padding = 128;
805  $fmt = 'ipv6gz';
806  $ip1 = ip_mangle($retarray['ip_numeric'], 'bin128');
807  $ip2 = str_pad(substr($ip1, 0, $retarray['mask_cidr']), $padding, '0');
808  $sub = gmp_sub("340282366920938463463374607431768211455", $retarray['mask_numeric']);
809  $total = gmp_strval(gmp_add($sub,'1'));
810  $usable = gmp_strval(gmp_sub($total,'2'));
811  $lastip = gmp_strval(gmp_add(gmp_sub(ip_mangle($ip2, 'numeric'),'1'),$total));
812  $retarray['ip_last'] = ip_mangle($lastip, 'ipv6');
813  }
814 
815  // Validate that the subnet IP & netmask combo are valid together.
816  $ip1 = ip_mangle($ip1, $fmt);
817  $ip2 = ip_mangle($ip2, $fmt);
818  $retarray['truenet'] = $ip2; // this is the subnet IP that your IP would fall in given the mask provided.
819  if ($ip1 != $ip2)
820  $retarray['netboundary'] = 0; // this means the IP passed in is NOT on a network boundary
821 
822  // Get IP address counts
823 
824  $retarray['ip_total'] = $total;
825  $retarray['ip_usable'] = $usable;
826 
827 
828  return($retarray);
829 }
830 
831 
832 
833 
834 
835 
836 
837 
838 
839 
840 
841 
842 
843 
844 
845 
846 
847 
849 // Function: sanitize_security_level($int, $default)
850 //
851 // Takes a string and returns either the same number if it's a valid
852 // security level or $default if $int is empty.
853 // Will return an error if the level is greater than your current
854 // level as defined in the session.
855 // Returns -1 on any error and stores a message in $self['error']
856 //
857 // Example:
858 // $level = sanitize_security_level($level)
860 function sanitize_security_level($string="", $default=-1) {
861  global $conf, $self;
862  if ($default == -1) $default = $conf['ona_lvl'];
863  if ($string == "") return($default);
864 
865  // If it's valid, use it..
866  if (is_numeric($string) and $string <= 99) {
867  // Make sure it's not higher than the user's current level
868  if ($string <= $_SESSION['auth']['user']['level'])
869  return($string);
870  else {
871  $self['error'] = "ERROR => Security-level can't be higher than your own level!";
872  return(-1);
873  }
874  }
875  else {
876  $self['error'] = "ERROR => Invalid security-level specified!";
877  return(-1);
878  }
879 }
880 
881 
882 
883 
884 
885 
886 
887 
888 
890 // Function: sanitize_hostname($string)
891 //
892 // Takes a string and returns either the same string if it's a valid
893 // hostname or FALSE if not.
894 // Returns FALSE on any error and stores a message in $self['error']
895 //
896 // Example:
897 // $hostname = sanitize_hostname('hostname');
898 // if ($hostname) { do($something); }
900 function sanitize_hostname($string="") {
901  global $self;
902  if ($string == "") { return(false); }
903 
904  // The rules for hostnames:
905  // * Must start and end with an alphanumeric character
906  // * Must consist of the valid character set: a-z0-9.-_
907  // * Can not have more than one consecutive period
908  // * Length must range between 1 and 63 characters
909 
910  // lets test out if it has a / in it to strip the view name portion
911  if (strstr($string,'/')) {
912  list($dnsview,$string) = explode('/', $string);
913  }
914 
915  // We lower case all dns names
916  $string = strtolower($string);
917 
918  // If it is a wildcard, let it through
919  if ($string == "*") { return($string); }
920 
921  // If it's valid, use it..
922  if (preg_match('/^([a-z0-9_\*]([a-z0-9_\.\-]*))?[a-z0-9]$/', $string)) {
923  // Make sure it doesn't have more than one "." in a row
924  if (stristr($string, '..')) { return(false); }
925  // The syntax is ok, make sure it's not too long
926  if (strlen($string) > 63) { return(false); }
927  // It's ok! Return it.
928  return($string);
929  }
930  $self['error'] = "ERROR => Invalid hostname!";
931  return(false);
932 }
933 
934 
935 
936 
937 
938 
939 
940 
941 
942 
943 
944 
945 
946 
948 // Function: mac_mangle($mac_address, [$format])
949 //
950 // $mac_address is a mac address in almost any format
951 // $format is the format the mac address will be returned in:
952 // 1 = non formatted raw form: A9B1CCD2392D
953 // 2 = typical format: A9:B1:CC:D2:39:2D
954 // 3 = cisco format: A9B1.CCD2.392D
955 //
956 // Formats the input MAC address into the format specified. When a
957 // format is not specified, and input is in format 2 or 3, format 1
958 // is returned -- if input is in format 1, format 2 is returned.
959 // Returns -1 on any error and stores a message in $self['error']
960 //
961 // Example:
962 // print "MAC is: " . mac_mangle('A9B1CCD2392D')
964 function mac_mangle($input="", $format="default") {
965  global $self;
966 
967  // Make sure we got input
968  if (!$input) { $self['error'] = "ERROR => MAC address was null"; return(-1); }
969 
970  $matches = array();
971 
972  // Is input in raw format? (1)
973  if (preg_match('/^([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})$/', $input, $matches)) {
974  if ($format == "default") { $format = 2; }
975  }
976 
977  // Is input in typical format? (2)
978  else if (preg_match('/^([A-Fa-f0-9]{2}).([A-Fa-f0-9]{2}).([A-Fa-f0-9]{2}).([A-Fa-f0-9]{2}).([A-Fa-f0-9]{2}).([A-Fa-f0-9]{2})$/', $input, $matches)) {
979  if ($format == "default") { $format = 1; }
980  }
981 
982  // Is input in cisco format? (3)
983  else if (preg_match('/^([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})\.([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})\.([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})$/', $input, $matches)) {
984  if ($format == "default") { $format = 1; }
985  }
986 
987  else {
988  $self['error'] = "ERROR => Invalid MAC address";
989  return(-1);
990  }
991 
992  // Output in format 1 (raw)?
993  if ($format == 1) {
994  return(strtoupper($matches[1] . $matches[2] . $matches[3] . $matches[4] . $matches[5] . $matches[6]));
995  }
996 
997  // Output in format 2 (typical)?
998  else if ($format == 2) {
999  return(strtoupper($matches[1] . ':' . $matches[2] . ':' . $matches[3] . ':' . $matches[4] . ':' . $matches[5] . ':' . $matches[6]));
1000  }
1001 
1002  // Output in format 2 (cisco)?
1003  else if ($format == 3) {
1004  return(strtoupper($matches[1] . $matches[2] . '.' . $matches[3] . $matches[4] . '.' . $matches[5] . $matches[6]));
1005  }
1006 
1007  else {
1008  $self['error'] = "ERROR => mac_mangle() Invalid MAC format specified!";
1009  return(-1);
1010  }
1011 
1012 }
1013 
1014 
1015 
1016 
1017 
1018 
1019 
1020 
1021 
1022 
1023 
1024 
1026 // Function: string ip_complete($ip, [$filler=0])
1027 //
1028 // Completes a partial ip address with $filler and returns it.
1029 // Returns -1 if the input string doesn't at least match /\d+\./
1030 //
1031 // $input is a partial or complete ip address in dotted format.
1032 // $filler is the number to replace incomplete ip pieces with.
1033 //
1034 // Examples:
1035 // $string = ip_complete('192.168', '0');
1036 // $string == '192.168.0.0'
1037 //
1038 // $string = ip_complete('192.168.', '255');
1039 // $string == '192.168.255.255'
1040 //
1041 // Note: If the IP address is invalid -1 is returned. So if the
1042 // input string is something like '192.515' -1 will be returned.
1044 function ip_complete($ip='', $filler=0) {
1045  global $self;
1046 
1047  // fix the : formats
1048  $ip = rawurldecode($ip);
1049 // THOUGHT: fill out :: with ffff:ffff .. need to figure out how many remaining octets there would be
1050 
1051  // This may break but leaving it in for now till testing can be done
1052  // I think it can be deleted but it at least needs to pad out whatever is passed
1053  if (strlen($ip) > 11) return($ip);
1054 
1055  // pad IPv6 ips that have XXXX: format
1056  // MP: FIXME: I would love to be able to search gz ipv6 addresses but its more complex to understand
1057  // when to pad with 0 or not per section. also when its compressed as :: how much is compressed?
1058  // as a user types in chars it would have to be evaluated against all formats. ugh
1059  // for now, you can only quick search full form ipv6 addresses not compressed IPS.
1060  if (@strpos($ip, ':',3) !== false) {
1061 
1062  if ($filler == '255') $filler = 'f';
1063  $ip = str_replace(':','',$ip);
1064 
1065  $startlen = strlen($ip);
1066 
1067  // loop and fill all remaining chars
1068  while ($startlen < 32) {
1069  $startlen++;
1070  $ip = $ip.$filler;
1071  }
1072 
1073  $ip = wordwrap($ip,4,':',true);
1074 
1075  return(ip_mangle($ip, 'ipv6'));
1076  }
1077 
1078  // Make sure it looks like a partial IP address
1079  if (!preg_match('/^(\d+)\.(\d+)?\.?(\d+)?\.?(\d+)?$/', $ip, $matches)) { return(-1); }
1080 
1081  // Build $ip with $filler
1082  $ip = $matches[1];
1083  if (is_numeric($matches[2])) { $ip .= ".{$matches[2]}"; } else { $ip .= ".{$filler}"; }
1084  if (is_numeric($matches[3])) { $ip .= ".{$matches[3]}"; } else { $ip .= ".{$filler}"; }
1085  if (is_numeric($matches[4])) { $ip .= ".{$matches[4]}"; } else { $ip .= ".{$filler}"; }
1086 
1087  return(ip_mangle($ip, 'dotted'));
1088 }
1089 
1090 
1091 
1092 
1093 
1094 
1095 
1096 
1097 
1099 // Function: date_mangle(int $timestamp | string $date)
1100 //
1101 // Returns int $timestamp as a MySQL formatted date string, or
1102 // Returns string $date (a onadb formatted date) as an int timestamp.
1103 // Returns -1 on error.
1105 function date_mangle($time=-1) {
1106  // Do a little input validation
1107  if ($time == -1) return(-1);
1108 
1109  if (preg_match('/(\d\d\d\d)\D(\d\d)\D(\d\d)\s+(\d\d)\D(\d\d)\D(\d\d)/', $time, $parts))
1110  $date = strtotime("{$parts[2]}/{$parts[3]}/{$parts[1]} {$parts[4]}:{$parts[5]}:{$parts[6]}");
1111  else
1112  $date = date('Y-m-d H:i:s', $time);
1113 
1114  return($date);
1115 }
1116 
1117 
1118 
1119 
1120 
1121 
1122 
1124 // Function: tzsecs($tz_offset)
1125 //
1126 // Returns the int $tz_offset * 60 * 60 .. effectivly converting the
1127 // timezone offset to seconds.
1129 function tzsecs($tz_offset=0) {
1130  return($tz_offset * 60 * 60);
1131 }
1132 
1133 
1134 
1135 
1136 
1137 
1138 
1140 // Function: gmtime()
1141 //
1142 // Returns the current UTC time in seconds since 1970.
1144 function gmtime() {
1145  $time = time() + (date('Z') * -1);
1146  return(date('U', $time));
1147 }
1148 
1149 
1150 
1151 
1152 
1154 // Function: validate_email($email_address)
1155 //
1156 // Returns the original string if it looks like a valid email address,
1157 // false if not.
1159 function validate_email($input) {
1160  if (preg_match('/^[A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,6}$/i', $input))
1161  return $input;
1162  return false;
1163 }
1164 
1165 
1166 
1167 
1168 
1170 // Function: validate_url($url)
1171 //
1172 // Returns the original string if it looks like a valid url,
1173 // false if not.
1175 function validate_url($input) {
1176  $input = strtolower($input);
1177  if (preg_match('/^\w+$/', $input))
1178  return $input;
1179  return false;
1180 }
1181 
1182 
1183 
1184 
1185 
1187 // Function: validate_username($username)
1188 //
1189 // Returns the original string if it looks like a valid email address,
1190 // false if not.
1192 function validate_username($input) {
1193  if (preg_match('/^[a-z0-9\.\-_]+$/i', $input))
1194  return $input;
1195  return false;
1196 }
1197 
1198 
1199 
1200 
1201 
1202 
1203 
1204 
1205 
1206 
1207 
1208 
1209 
1211 // Function: startSession()
1212 //
1213 // Call this function to start the PHP session
1214 // This function should not be used in place of securePage()!
1215 // This function does not make sure they have a valid username,
1216 // call securePage() first.
1217 //
1218 // Returns 0 on success, 1 on failure.
1219 //
1221 function startSession() {
1222  global $conf;
1223 
1224  // If the command line agent, dcm.pl, is making the request, don't really start a session.
1225  if (preg_match('/console-module-interface/', $_SERVER['HTTP_USER_AGENT'])) {
1226 
1227  // Pretend to log them in
1228  if (preg_match('/unix_username=([^&]+?)(&|$)/', $_REQUEST['options'], $matches)) {
1229  $_SESSION['ona']['auth']['user']['username'] = $matches[1];
1230  }
1231 
1232  return(1);
1233  }
1234 
1235  // Set the name of the cookie (nicer than default name)
1236  session_name("ONA_SESSION_ID");
1237 
1238  // Set cookie to expire at end of session
1239  // secure cookie
1240  if (isset($_SERVER['HTTPS']) && 'on' == $_SERVER['HTTPS']) {
1241 
1242  session_set_cookie_params(0, '/', $_SERVER["SERVER_NAME"], 1);
1243  }
1244  // normal cookie
1245  else {
1246  session_set_cookie_params(0, '/');
1247  }
1248 
1249  // (Re)start the session
1250  session_start();
1251 
1252  // According to PHP.net comment this is a good thing to do:
1253  // http://us2.php.net/manual/en/function.session-start.php
1254  header("Cache-control: private");
1255 
1256  // Display session variables
1257 // if ($conf['debug'] >= 0) {
1258 // print "Session Variables:<pre>";
1259 // var_export($_SESSION);
1260 // print "</pre>\n";
1261 // }
1262 
1263  return(0);
1264 }
1265 
1266 
1267 
1268 
1269 
1270 
1271 
1272 
1273 
1275 // Function: securePage()
1276 //
1277 // Call this function at the top of each page that needs to be
1278 // secure (i.e. it requires a user who is properly logged in)
1279 //
1280 // MP: not used currently.. login is built into the html_desktop
1281 //
1283 function securePage() {
1284  global $conf;
1285 
1286  // If the sessionID is not present start the session (reading the
1287  // users cookie and loading their settings from disk)
1288  if ( ONA_SESSION_ID != "" ) startSession();
1289 
1290  // Make sure their session is still active
1291  if (!(isset($_SESSION['ona']['auth']['user']['username']))) {
1292  //header("Location: {$https}{$baseURL}/login.php?expired=1");
1293  exit();
1294  }
1295 
1296  return(0);
1297 }
1298 
1299 
1300 
1301 
1302 
1303 
1304 
1305 
1306 
1308 // Function: loggedIn()
1309 //
1310 // Returns true if the user is authenticated, false if not
1311 //
1313 function loggedIn() {
1314  // Make sure their session is still active
1315  if (isset($_SESSION['ona']['auth']['user']['username']))
1316  return true;
1317  return false;
1318 }
1319 
1320 
1321 
1322 
1323 
1324 
1325 
1327 // Returns true if the current user has access to the requested resource,
1328 // false if not.
1330 function auth($resource,$msg_level=1) {
1331 
1332  if (!is_string($resource)) return false;
1333  if (array_key_exists($resource, (array)$_SESSION['ona']['auth']['perms'])) {
1334  printmsg("DEBUG => auth() User[{$_SESSION['ona']['auth']['user']['username']}] has the {$resource} permission",5);
1335  return true;
1336  }
1337  printmsg("DEBUG => auth() User[{$_SESSION['ona']['auth']['user']['username']}] does not have the {$resource} permission",$msg_level);
1338  return false;
1339 }
1340 
1341 
1342 
1343 
1344 
1346 // Returns true if the current user has a "level" greater than or equal to
1347 // the level passed into the function. Returns false if not.
1349 function authlvl($level) {
1350 
1351  // FIXME: hack until we get auth stuff working:
1352  printmsg("DEBUG => FIXME: authlvl() always returns true for now", 1);
1353  return true;
1354 
1355  if (!is_numeric($level)) return false;
1356  if ($_SESSION['ona']['auth']['user']['level'] >= $level) {
1357  printmsg("DEBUG => authlvl() {$_SESSION['ona']['auth']['user']['username']}'s level is >= {$level}",1);
1358  return true;
1359  }
1360  printmsg("DEBUG => authlvl() {$_SESSION['ona']['auth']['user']['username']}'s level is not >= {$level}",1);
1361  return false;
1362 }
1363 
1364 
1365 
1366 
1368 // Function: load_module($name)
1369 //
1370 // Runs a require_once($filename) to load the module named $name
1371 // Returns 0 on success, 1 on failure. On failure $self['error']
1372 // will contain an error description.
1373 // Note: $conf['dcm_module_dir'] must be defined!
1374 //
1375 // Example:
1376 // load_module('my_module');
1378 function load_module($name='') {
1379  global $conf, $self, $onadb;
1380 
1381  if (!$name) {
1382  $self['error'] = "ERROR => load_module() No module specified!";
1383  return(1);
1384  }
1385 
1386  // If the module is already loaded, return success
1387  if (function_exists($name)) { return(0); }
1388 
1389  // Make sure we're connected to the DB
1390  // require_once($conf['inc_functions_db']);
1391 
1392  // Use cache if possible
1393  if (!is_array($self['cache']['modules']) or !array_key_exists('get_module_list', $self['cache']['modules'])) {
1394  // Get a list of the valid "modules" and their descriptions.
1395  require_once($conf['dcm_module_dir'] . '/get_module_list.inc.php');
1396  list($status, $self['cache']['modules']) = get_module_list('type=array');
1397  }
1398 
1399  // Make sure the user requested a valid "module"
1400  if (!array_key_exists($name, $self['cache']['modules'])) {
1401  // Otherwise print an error
1402  $self['error'] = "ERROR => The requested module is not valid!";
1403  return(1);
1404  }
1405 
1406  // Make sure the include file containing the function(s)/module(s) requested exists..
1407  // We have to find out which file it's in.
1408  list($status, $rows, $module) = db_get_record($onadb, 'dcm_module_list', array('name' => $name));
1409  if ($status or $rows != 1) {
1410  $self['error'] = 'ERROR => The specified module does not exist';
1411  return(1);
1412  }
1413  $file = $conf['dcm_module_dir'] . '/' . $module['file'];
1414 
1415  if (!is_file($file)) {
1416  // Otherwise print an error
1417  $self['error'] = "ERROR => The include file ({$file}) for the {$name} module doesn't exist!";
1418  return(1);
1419  }
1420 
1421  // Include the file
1422  // The file should define a function called generate_config() to which we pass a node-name,
1423  // and receive a configuration file.
1424  require_once($file);
1425 
1426  // Test that the module function existed in the file we just loaded
1427  if (!function_exists($name)) {
1428  $self['error'] = "ERROR => The module function {$name} doesn't exist in file: {$file}";
1429  return(1);
1430  }
1431 
1432  return(0);
1433 }
1434 
1435 
1436 
1437 
1438 
1439 
1440 
1441 
1442 
1443 
1445 // Function: run_module(string $module, string or array $module_options, $transaction=1)
1446 //
1447 // Runs the specified module and returns the status and output
1448 // of the specified module.
1449 //
1450 // Input Values:
1451 // $module = the name of the module to run.
1452 // $options = an array of key => value pairs to pass to the module,
1453 // or an already formatted string of the key => value
1454 // pairs.
1455 // $transaction = set to 0 or false to disable transaction code.
1456 //
1457 // Return Values:
1458 // Returns a two part array: array($status, $output)
1459 // $status = exit status of the specified module, generally 0 on
1460 // success and non-zero on error.
1461 // $output = textual output of the specified module. This can
1462 // occasionally be an error message generated by this
1463 // function itself.
1464 //
1465 // Example:
1466 // list($status, $text) = run_module('alias_del', array('alias' => 'time01'));
1468 function run_module($module='', $options='', $transaction=1) {
1469  global $conf, $self, $onadb;
1470 
1471  // Build the options array string from $options_string if we need to
1472  // This is only used for logging! If $options_string is an array it
1473  // is passed untouched to the module.
1474  $options_string = $options;
1475  if (is_array($options)) {
1476  $options_string = '';
1477  $and = '';
1478  foreach (array_keys($options) as $key) {
1479  // Quote any "special" characters in the value.
1480  // Specifically the '=' and '&' characters need to be escaped.
1481  $options[$key] = str_replace(array('=', '&'), array('\=', '\&'), $options[$key]);
1482  // If the key has no value or it is the javascript key, dont print it.
1483  if (($options[$key] != "") and ($key != 'js')) {
1484  $options_string .= "{$and}{$key}={$options[$key]}";
1485  $and = '&';
1486  }
1487  }
1488  }
1489 
1490  // get the options as an array so we can look for logging info
1491  $local_options = parse_options($options);
1492 
1493  // If the user passes in an option called 'module_loglevel' then use it as the run module output level
1494  // otherwise default it to 1 so it will print out as normal.
1495  $log_level = 1;
1496  if ($local_options['module_loglevel']) {
1497  $log_level = $local_options['module_loglevel'];
1498  }
1499 
1500  // Remove config info as it can be huge and could have sensitive info in it.
1501  // This could cause issues since I"m doing & as an anchor at the end. see how it goes.
1502  // The module that is called could also display this information depending on debug level
1503  $options_string = preg_replace("/config=.*&/", '', $options_string);
1504 
1505  printmsg("INFO => Running module: {$module} options: {$options_string}", $log_level);
1506 
1507  // Load the module
1508  if (load_module($module)) { return(array(1, $self['error'] . "\n")); }
1509 
1510  // Start an DB transaction (If the database supports it)
1511  if ($transaction) $has_trans = $onadb->BeginTrans();
1512  if (!$has_trans) printmsg("WARNING => Transactions support not available on this database, this can cause problems!", 1);
1513 
1514  // If begintrans worked and we support transactions, do the smarter "starttrans" function
1515  if ($has_trans) {
1516  printmsg("DEBUG => Commiting transaction", 2);
1517  $onadb->StartTrans();
1518  }
1519 
1520  // Start a timer so we can display moudle run time if debugging is enabled
1521  $start_time = microtime_float();
1522 
1523  // Run the function
1524  list($status, $output) = $module($options);
1525 
1526  // Stop the timer, and display how long it took
1527  $stop_time = microtime_float();
1528  printmsg("DEBUG => [Module_runtime] " . round(($stop_time - $start_time), 2) . " seconds -- [Total_SQL_Queries] " . $self['db_get_record_count'] . " -- [Module_exit_code] {$status}", 1);
1529 
1530  // Either commit, or roll back the transaction
1531  if ($transaction and $has_trans) {
1532  if ($status != 0) {
1533  printmsg("INFO => There was a module error, marking transaction for a Rollback!", 1);
1534  //$onadb->RollbackTrans();
1535  $onadb->FailTrans();
1536  }
1537  }
1538 
1539  if ($has_trans) {
1540  // If there was any sort of failure, make sure the status has incremented, this catches sub module output errors;
1541  if ($onadb->HasFailedTrans()) $status = $status + 1;
1542 
1543  // If the user passed the rollback flag then dont commit the transaction
1544 // FIXME: not complete or tested.. it would be nice to have an ability for the user to pass
1545 // a rollback flag to force the transaction to rollback.. good for testing adds/modify.
1546 // The problem is sub modules will fire and then the whole thing stops so you wont see/test the full operation.
1547 // if ($local_options['rollback']) {
1548 // printmsg("INFO => The user requested to mark the transaction for a rollback, no changes made.", 0);
1549 // $output .= "INFO => The user requested to mark the transaction for a rollback, no changes made.\n";
1550 // $status = $status + 1;
1551 // }
1552 
1553  printmsg("DEBUG => Commiting transaction", 2);
1554  $onadb->CompleteTrans();
1555  }
1556 
1557  // Return the module's output
1558  return(array($status, $output));
1559 }
1560 
1561 
1562 
1563 
1564 
1565 
1566 
1568 // Function: parse_options($options)
1569 //
1570 // Takes an options string (passed to a dcm module) and returns
1571 // an array of the key=value pairs included in it.
1572 // Values are allowed to contain "=" and "&" characters as long as
1573 // they are escaped with a "\" character.
1574 //
1575 // Example:
1576 // $options = parse_options('key=value&key2=value2');
1577 // if ($options['key'] == 'value') { Blah; }
1579 function parse_options($options="") {
1580 
1581  // If it's already an array, just return it
1582  if (is_array($options)) { return($options); }
1583 
1584  $newoptions = array();
1585 
1586  // Replace "\&" and "\=" with a random string
1587  $replace_and = '{' . md5(mt_rand(100000, 900000)) . '}';
1588  $replace_eq = '{' . md5(mt_rand(100000, 900000)) . '}';
1589  $options = str_replace(
1590  array('\&', '\='),
1591  array($replace_and, $replace_eq),
1592  $options
1593  );
1594 
1595  // Parse incoming options - split on '&'
1596  foreach (explode('&', $options) as $set) {
1597  $pair = array('','');
1598 
1599  // Now split on '='
1600  $pair = explode('=', $set);
1601 
1602  // Replace previously escaped & and = characters with the real thing
1603  $pair = str_replace(
1604  array($replace_and, $replace_eq),
1605  array('&', '='),
1606  $pair);
1607 
1608  // And set the key=value in $newoptions
1609  $newoptions[$pair[0]] = $pair[1];
1610  }
1611 
1612  return($newoptions);
1613 }
1614 
1615 
1616 
1617 
1618 
1619 
1620 
1621 
1622 
1623 
1624 
1625 
1626 
1627 
1629 // Function: sanitize_YN($string, $default)
1630 //
1631 // Takes a string and returns either 'Y' or 'N'. 'Y' is returned
1632 // by default if $string is empty, unless $default is changed.
1633 //
1634 // Example:
1635 // $string = sanitize_YN($string)
1637 function sanitize_YN($string="", $default="Y") {
1638  if ($string == "")
1639  return($default);
1640  $string = strtolower($string);
1641  if ($string == 'no' or $string == 'n' or $string == 'off' or $string == '0')
1642  return('N');
1643  else if ($string == 'yes' or $string == 'y' or $string == 'on' or $string == '1')
1644  return('Y');
1645  else
1646  return($default);
1647 }
1648 
1649 
1650 
1651 
1652 
1653 
1654 
1655 
1656 
1667 function html_diff($old, $new, $oldname='', $newname='', $stdout=1) {
1668  global $conf;
1669  $html = '';
1670 
1671  if(!($old and $new)) return('ERROR => Insufficient parameters passed to html_diff()!');
1672 
1673  // Load diff code
1674  require_once($conf['inc_diff']);
1675 
1676  $df = new Diff(explode("\n",htmlspecialchars($old)),
1677  explode("\n",htmlspecialchars($new)));
1678  $tdf = new TableDiffFormatter();
1679 
1680  $html .= <<<EOL
1681 \n <table class="diff" width="100%">
1682  <tr>
1683  <td colspan="2" width="50%" class="diff-header">
1684  {$oldname}
1685  </td>
1686  <td colspan="2" width="50%" class="diff-header">
1687  {$newname}
1688  </td>
1689  </tr>
1690 EOL;
1691  $html .= $tdf->format($df) . "</table>";
1692 
1693  if ($stdout)
1694  echo $html;
1695  else
1696  return($html);
1697 }
1698 
1699 
1700 
1701 
1702 
1703 
1713 function text_diff($old, $new) {
1714  global $conf;
1715  $html = '';
1716 
1717  if(!($old and $new)) return('ERROR => Insufficient parameters passed to text_diff()!');
1718 
1719  // Load diff code
1720  require_once($conf['inc_diff']);
1721 
1722  $df = new Diff(explode("\n",$old),
1723  explode("\n",$new));
1724  $tdf = new UnifiedDiffFormatter();
1725 
1726  $text .= $tdf->format($df);
1727 
1728  return($text);
1729 }
1730 
1731 
1732 
1733 
1734 
1736 // Function: format_array($array)
1737 //
1738 // Takes an array and returns a formatted string of the contents
1739 // of the array for display. Usually used in the ona_xxx_display()
1740 // functions to display database records.
1741 //
1742 // Example:
1743 // $string = format_array($array)
1745 function format_array($array=array()) {
1746 
1747  $text = '';
1748  foreach (array_keys($array) as $key) {
1749 
1750  // Make some data look pretty
1751  if ($key == 'ip_addr') { $array[$key] = ip_mangle($array[$key], 'dotted'); }
1752  else if ($key == 'ip_addr_start') { $array[$key] = ip_mangle($array[$key], 'dotted'); }
1753  else if ($key == 'ip_addr_end') { $array[$key] = ip_mangle($array[$key], 'dotted'); }
1754  else if ($key == 'ip_mask') { $array[$key] = ip_mangle($array[$key]). ' (/'.ip_mangle($array[$key],'cidr').')'; }
1755  else if ($key == 'mac_addr') { $array[$key] = mac_mangle($array[$key]); if ($array[$key] == -1) $array[$key] = ''; }
1756  else if ($key == 'host_id') {
1757  list($status, $rows, $host) = ona_find_host($array[$key]);
1758  if ($host['id'])
1759  $array[$key] = str_pad($array[$key], 20) . strtolower("({$host['fqdn']})");
1760  }
1761  else if ($key == 'server_id') {
1762  list($status, $rows, $server) = ona_get_server_record(array('id' => $array[$key]));
1763  list($status, $rows, $host) = ona_find_host($server['host_id']);
1764  if ($host['id'])
1765  $array[$key] = str_pad($array[$key], 20) . strtolower("({$host['fqdn']})");
1766  }
1767  else if ($key == 'subnet_id') {
1768  list($status, $rows, $subnet) = ona_get_subnet_record(array('id' => $array[$key]));
1769  if ($subnet['id'])
1770  $array[$key] = str_pad($array[$key], 20) . strtoupper("({$subnet['name']})");
1771  }
1772  else if ($key == 'domain_id' or $key == 'primary_dns_domain_id') {
1773  list($status, $rows, $domain) = ona_get_domain_record(array('id' => $array[$key]));
1774  $array[$key] = str_pad($array[$key], 20) . strtolower("({$domain['fqdn']})");
1775  }
1776  else if ($key == 'interface_id') {
1777  list($status, $rows, $interface) = ona_get_interface_record(array('id' => $array[$key]));
1778  $array[$key] = str_pad($array[$key], 20) . '(' .ip_mangle($interface['ip_addr'], 'dotted') . ')';
1779  }
1780  else if ($key == 'device_type_id') {
1781  list($status, $rows, $devtype) = ona_get_device_type_record(array('id' => $array[$key]));
1782  if ($devtype['id']) {
1783  list($status, $rows, $model) = ona_get_model_record(array('id' => $devtype['model_id']));
1784  list($status, $rows, $role) = ona_get_role_record(array('id' => $devtype['role_id']));
1785  list($status, $rows, $manu) = ona_get_manufacturer_record(array('id' => $model['manufacturer_id']));
1786  $array[$key] = str_pad($array[$key], 20) . "({$manu['name']}, {$model['name']} ({$role['name']}))";
1787  }
1788  }
1789  else if ($key == 'custom_attribute_type_id') {
1790  list($status, $rows, $ca) = ona_get_custom_attribute_type_record(array('id' => $array[$key]));
1791  if ($ca['id'])
1792  $array[$key] = str_pad($array[$key], 20) . "({$ca['name']})";
1793  }
1794 
1795  // Align columns
1796  if ($array[$key]) { $text .= str_pad(" {$key}", 30) . $array[$key] . "\n"; }
1797  }
1798 
1799  // Return a nice string :)
1800  return($text);
1801 }
1802 
1803 
1804 
1805 
1806 
1807 
1808 
1809 
1810 
1811 
1812 ?>
db_insert_record
db_insert_record($dbh=0, $table="", $insert="")
Definition: functions_db.inc.php:375
ona_get_manufacturer_record
ona_get_manufacturer_record($array)
Definition: functions_db.inc.php:1210
sanitize_YN
sanitize_YN($string="", $default="Y")
Definition: functions_general.inc.php:1637
cleanText
cleanText($text)
Definition: functions_general.inc.php:252
$stdout
$stdout
Definition: installcli.php:80
loggedIn
loggedIn()
Definition: functions_general.inc.php:1313
ip_mangle
ip_mangle($ip="", $format="default")
Definition: functions_general.inc.php:308
ona_get_interface_record
ona_get_interface_record($array='', $order='')
Definition: functions_db.inc.php:1126
ip_mangle_no_gmp
ip_mangle_no_gmp($ip="", $format="default")
Definition: functions_general.inc.php:350
ona_find_host
ona_find_host($search="")
Definition: functions_db.inc.php:1490
securePage
securePage()
Definition: functions_general.inc.php:1283
exit
exit
Definition: config.inc.php:186
$status
$status
Definition: install.php:12
$onadb
global $onadb
Definition: 2-to-3.php:15
fix_input
fix_input($string)
Definition: functions_general.inc.php:230
mac_mangle
mac_mangle($input="", $format="default")
Definition: functions_general.inc.php:964
tzsecs
tzsecs($tz_offset=0)
Definition: functions_general.inc.php:1129
$username
$username
Definition: collate-convert.php:16
load_module
load_module($name='')
Definition: functions_general.inc.php:1378
TableDiffFormatter
Definition: DifferenceEngine.php:973
ona_get_role_record
ona_get_role_record($array)
Definition: functions_db.inc.php:1222
ona_logmsg
ona_logmsg($message, $logfile="")
Definition: functions_general.inc.php:113
validate_url
validate_url($input)
Definition: functions_general.inc.php:1175
ona_get_device_type_record
ona_get_device_type_record($array)
Definition: functions_db.inc.php:1214
ona_get_model_record
ona_get_model_record($array)
Definition: functions_db.inc.php:1197
printmsg
if(6<=$conf['debug']) printmsg($msg="", $debugLevel=0)
Definition: functions_general.inc.php:48
strsize
strsize($string)
Definition: functions_general.inc.php:180
truncate
truncate($msg="", $length=0)
Definition: functions_general.inc.php:209
format_array
format_array($array=array())
Definition: functions_general.inc.php:1745
ipcalc_info
ipcalc_info($ip='', $mask='')
Definition: functions_general.inc.php:748
authlvl
authlvl($level)
Definition: functions_general.inc.php:1349
$host
$host
Definition: collate-convert.php:19
gmtime
gmtime()
Definition: functions_general.inc.php:1144
get_module_list
get_module_list($options="type=string")
Definition: get_module_list.inc.php:23
run_module
run_module($module='', $options='', $transaction=1)
Definition: functions_general.inc.php:1468
ip_complete
ip_complete($ip='', $filler=0)
Definition: functions_general.inc.php:1044
text_diff
text_diff($old, $new)
Definition: functions_general.inc.php:1713
validate_username
validate_username($input)
Definition: functions_general.inc.php:1192
UnifiedDiffFormatter
Definition: DifferenceEngine.php:942
EOL
< a style="text-decoration: none;" href="/">< input class='edit' type="button" value="I don't like free stuff?" onclick=""/></a ></center ></div > EOL
Definition: install.php:40
sanitize_hostname
sanitize_hostname($string="")
Definition: functions_general.inc.php:900
$_SESSION
$_SESSION['ona']['auth']
Definition: login.php:14
$conf
global $conf
Definition: 2-to-3.php:15
$ip
$ip
Definition: main.inc.php:24
ona_get_domain_record
ona_get_domain_record($array='', $order='')
Definition: functions_db.inc.php:1134
$output
$output
Definition: dcm.php:16
html_diff
html_diff($old, $new, $oldname='', $newname='', $stdout=1)
Definition: functions_general.inc.php:1667
validate_email
validate_email($input)
Definition: functions_general.inc.php:1159
$text
$text
Definition: install.php:11
ip_mangle_gmp
ip_mangle_gmp($ip="", $format="default")
Definition: functions_general.inc.php:472
$self
global $self
Definition: 2-to-3.php:15
db_get_record
db_get_record($dbh=0, $table="", $where="", $order="")
Definition: functions_db.inc.php:708
ona_get_custom_attribute_type_record
ona_get_custom_attribute_type_record($array)
Definition: functions_db.inc.php:1179
auth
auth($resource, $msg_level=1)
Definition: functions_general.inc.php:1330
ona_get_subnet_record
ona_get_subnet_record($array)
Definition: functions_db.inc.php:1226
$message
$message
Definition: login.php:37
microtime_float
microtime_float()
Definition: functions_general.inc.php:267
date_mangle
date_mangle($time=-1)
Definition: functions_general.inc.php:1105
parse_options
parse_options($options="")
Definition: functions_general.inc.php:1579
startSession
startSession()
Definition: functions_general.inc.php:1221
sanitize_security_level
sanitize_security_level($string="", $default=-1)
Definition: functions_general.inc.php:860
Diff
Definition: DifferenceEngine.php:492