PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/html/lib/3rdparty/freenac/wsus_sync.php

https://gitlab.com/Maskerade/patchdashboard
PHP | 245 lines | 164 code | 29 blank | 52 comment | 27 complexity | 4ae4d08b546db5312c14bdcad49d262d MD5 | raw file
  1. <?php
  2. /**
  3. * PHP version 5
  4. *
  5. * LICENSE: This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as published
  7. * by the Free Software Foundation.
  8. *
  9. * @package FreeNAC
  10. * @author Wolfram Strauss, Hector Ortiz (FreeNAC Core Team)
  11. * @copyright 2006 FreeNAC
  12. * @license http://www.gnu.org/copyleft/gpl.html GNU Public License Version 2
  13. * @version CVS: $Id:$
  14. * @link http://www.freenac.net
  15. *
  16. */
  17. /**
  18. * Obtain update status from the wsus database and store locally.
  19. */
  20. /* * *****************************
  21. FUNCTIONS
  22. * ***************************** */
  23. /**
  24. * This function converts the datetime retrieved from MSSQL into MySQL datetime format
  25. */
  26. function convert_date($date) {
  27. $date_array = getdate(strtotime($date));
  28. $date = $date_array['year'] . '-';
  29. $date_array['mon'] < 10 ? $date.='0' . $date_array['mon'] . '-' : $date.=$date_array['mon'] . '-';
  30. $date_array['mday'] < 10 ? $date.='0' . $date_array['mday'] . ' ' : $date.=$date_array['mday'] . ' ';
  31. $date_array['hours'] < 10 ? $date.='0' . $date_array['hours'] . ':' : $date.=$date_array['hours'] . ':';
  32. $date_array['minutes'] < 10 ? $date.='0' . $date_array['minutes'] . ':' : $date.=$date_array['minutes'] . ':';
  33. $date_array['seconds'] < 10 ? $date.='0' . $date_array['seconds'] : $date.=$date_array['seconds'];
  34. return $date;
  35. }
  36. /**
  37. * Ensures that $string is mysql safe
  38. */
  39. function validate($string) {
  40. rtrim($string, ' ');
  41. if (get_magic_quotes_gpc()) {
  42. $value = stripslashes($string);
  43. }
  44. if (!is_numeric($string)) {
  45. $string = mysql_real_escape_string($string);
  46. }
  47. return $string;
  48. }
  49. /**
  50. * Connect to the WSUS server
  51. */
  52. function dbwsus_connect() {
  53. global $conf, $wsus_dbuser, $wsus_dbpass, $logger;
  54. $logger->debug("Connecting to " . $conf->wsus_dbalias . " " . $conf->wsus_db, 1);
  55. $msconnect = mssql_connect($conf->wsus_dbalias, $wsus_dbuser, $wsus_dbpass);
  56. if (!$msconnect) {
  57. $logger->logit("Cannot connect to WSUS server " . $conf->wsus_dbalias . ":" . mssql_get_last_message(), LOG_ERR);
  58. return false;
  59. }
  60. $db = mssql_select_db($conf->wsus_db, $msconnect);
  61. if (!$db) {
  62. $logger->logit("Couldn't open database " . $conf->wsus_db . " " . mssql_get_last_message(), LOG_ERR);
  63. return false;
  64. }
  65. }
  66. /**
  67. * Returns the hostname part of an fqdn thus everything before the first dot
  68. */
  69. function get_hostname($fqdn) {
  70. global $logger;
  71. $dot_pos = strpos($fqdn, '.'); // find position of first dot
  72. $hostname;
  73. if ($dot_pos) {
  74. $hostname = substr($fqdn, 0, $dot_pos); // take everything before the first dot
  75. } else {
  76. $hostname = $fqdn;
  77. }
  78. $logger->debug("Converting $fqdn to $hostname", 2);
  79. return strtolower($hostname);
  80. }
  81. /**
  82. * Look up a wsus hostname in the vmps table and return the vmps id if and only if there's exactly one entry
  83. */
  84. function get_vmps_id($hostname) {
  85. global $logger;
  86. $logger->debug("Looking for vmps system id for hostname $hostname", 1);
  87. $query = "select id from systems where substring_index(last_hostname, '.', 1) = '$hostname';";
  88. $logger->debug("Executing: $query", 3);
  89. $result = mysql_query($query);
  90. if (!$result) {
  91. $logger->logit("Could not obtain vmps id for $hostname, " . mysql_error(), LOG_WARNING);
  92. return false;
  93. }
  94. $num_rows = mysql_num_rows($result); //TODO: exception handling
  95. if ($num_rows == 0) {
  96. //$logger->logit("No vmps id for system $hostname found", LOG_WARNING);
  97. $logger->logit("No vmps id for system $hostname found"); // don't flag as warning until 100% right, its flooding logcheck
  98. return false;
  99. } elseif ($num_rows == 1) {
  100. $row = mysql_fetch_row($result); //TODO: exception handling
  101. $logger->debug("hostname $hostname has vmps id $row[0]", 1);
  102. return $row[0];
  103. } else {
  104. //$logger->logit("$hostname is not unique in vmps", LOG_WARNING);
  105. $logger->logit("$hostname is not unique in vmps"); // don't flag as warning until 100% right, its flooding logcheck
  106. return false;
  107. }
  108. }
  109. /**
  110. * Empty all wsus tables.
  111. */
  112. function empty_tables() {
  113. global $logger;
  114. $logger->debug("Emptying wsus tables", 1);
  115. # As of MySQL 5.1.6, truncate requires the DROP privilege
  116. #if( !mysql_query('truncate table wsus_systems;') ) {
  117. if (!mysql_query('delete from wsus_systems;')) {
  118. $logger->logit("Could not empty wsus_systems, " . mysql_error(), LOG_ERR);
  119. return false;
  120. }
  121. #if( !mysql_query('truncate table wsus_neededUpdates;') ) {
  122. if (!mysql_query('delete from wsus_neededUpdates;')) {
  123. $logger->logit("Could not empty wsus_neededUpdates, " . mysql_error(), LOG_ERR);
  124. return false;
  125. }
  126. #if( !mysql_query('truncate table wsus_systemToUpdates;') ) {
  127. if (!mysql_query('delete from wsus_systemToUpdates;')) {
  128. $logger->logit("Could not empty wsus_systemToUpdate, " . mysql_error(), LOG_ERR);
  129. return false;
  130. }
  131. return true;
  132. }
  133. /**
  134. * Get global list of needed updates from wsus db and store in openac db
  135. */
  136. function get_global_update_list() {
  137. global $logger, $timestamp;
  138. // A summarizationstate of 4 references updates that a properly installed. These are the only ones we are not interested in. Languageid 1033 is english, thus we only fetch the english descriptions for the udpates
  139. $query = "select distinct u.localupdateid, lp.title, lp.description, p.msrcseverity, p.creationdate, p.receivedfromcreatorservice from susdb.dbo.tbupdatestatuspercomputer us left join susdb.dbo.tbupdate u on us.localupdateid = u.localupdateid left join dbo.tbrevision r on u.localupdateid = r.localupdateid left join dbo.tbproperty p on r.revisionid = p.revisionid left join dbo.tblocalizedpropertyforrevision lpr on r.revisionid = lpr.revisionid left join dbo.tblocalizedproperty lp on lpr.localizedpropertyid = lp.localizedpropertyid where (us.summarizationstate <> 4) and (us.summarizationstate <> 1) and lpr.languageid = 1033 and r.revisionid = (select max(r.revisionid) from tbrevision r where r.localupdateid = u.localupdateid)";
  140. $logger->debug("Executing: " . $query, 3);
  141. $result = mssql_query($query);
  142. if (!$result) {
  143. $logger->logit("Could not fetch global update list, " . mssql_get_last_message(), LOG_ERR);
  144. return false;
  145. }
  146. ;
  147. while ($row = mssql_fetch_assoc($result)) {
  148. $query = sprintf("insert into wsus_neededUpdates(localupdateid, title, description, msrcseverity, creationdate, receiveddate, lastsync) values('%s', '%s', '%s', '%s', '%s', '%s', '%s');", validate($row['localupdateid']), validate($row['title']), validate($row['description']), validate($row['msrcseverity']), convert_date($row['creationdate']), convert_date($row['receivedfromcreatorservice']), $timestamp);
  149. $logger->debug("Executing: $query", 3);
  150. if (!mysql_query($query)) {
  151. $logger->logit("Could insert update list into vmps db, " . mysql_error(), LOG_ERR);
  152. return false;
  153. }
  154. }
  155. return true;
  156. }
  157. /**
  158. * Obtain list of system which are registerd in the wsus server, fetch their status for each necessary update and write everything into the vmps db
  159. */
  160. function get_systems() {
  161. global $logger, $timestamp;
  162. $query = "select t.targetid, t.fulldomainname, t.ipaddress, t.lastreportedstatustime, s.notinstalled, s.downloaded, s.installedpendingreboot, s.failed, d.computermake, d.computermodel, o.oslongname from dbo.tbcomputertarget t left join dbo.tbcomputersummaryformicrosoftupdates s on t.targetid = s.targetid left join dbo.tbcomputertargetdetail d on t.targetid = d.targetid left join dbo.tbosmap o on (d.osminorversion = o.osminorversion and d.osmajorversion = o.osmajorversion and d.osservicepackmajornumber = o.osservicepackmajornumber) where (o.processorarchitecture is null or o.processorarchitecture = 1)";
  163. $logger->debug("Executing: $query", 3);
  164. $result = mssql_query($query);
  165. if (!$result) {
  166. $logger->logit("Failed to obtain systems from wsus, " . mssql_get_last_message(), LOG_ERR);
  167. return false;
  168. }
  169. while ($sys_row = mssql_fetch_assoc($result)) {
  170. $hostname = get_hostname($sys_row['fulldomainname']);
  171. $id = get_vmps_id($hostname);
  172. if (!$id) {
  173. continue;
  174. }
  175. $query = sprintf("select us.localupdateid from dbo.tbupdatestatuspercomputer us where (us.summarizationstate <> 4) and (us.summarizationstate <> 1) and us.targetid = '%s'", $sys_row['targetid']);
  176. $logger->debug("Executing: $query", 3);
  177. $result_update = mssql_query($query);
  178. if (!$result) { // whenever there occurs an error we skip the current system and continue with the next one
  179. $logger->logit("Could not fetch update details for " . $sys_row['fulldomainname'] . ", skipping this system", LOG_WARNING);
  180. continue;
  181. }
  182. // insert system into wsus_systems
  183. $query = sprintf("insert into wsus_systems values('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s');", $id, $hostname, validate($sys_row['ipaddress']), convert_date($sys_row['lastreportedstatustime']), validate($sys_row['oslongname']), validate($sys_row['computermake']), validate($sys_row['computermodel']), validate($sys_row['notinstalled']), validate($sys_row['downloaded']), validate($sys_row['installedpendingreboot']), validate($sys_row['failed']), $timestamp);
  184. $logger->debug("Executing: $query", 3);
  185. if (!mysql_query($query)) {
  186. $logger->logit("Could not insert system $hostname, " . mysql_error(), LOG_WARNING);
  187. continue;
  188. }
  189. // insert mapping to needed updates
  190. while ($update_row = mssql_fetch_assoc($result_update)) {
  191. $query = sprintf("insert into wsus_systemToUpdates(sid, localupdateid, lastsync) values('%s', '%s', '%s');", $id, validate($update_row['localupdateid']), $timestamp);
  192. $logger->debug("Executing $query", 3);
  193. if (!mysql_query($query)) {
  194. $logger->logit("Could not insert update relation $id, " . $update_row['localupdateid'], LOG_WARNING);
  195. }
  196. }
  197. }
  198. return true;
  199. }
  200. /**
  201. *
  202. */
  203. function cleanup() {
  204. global $logger;
  205. // TODO: exception handling
  206. mssql_close();
  207. mysql_close();
  208. $logger->logit("Done syncing WSUS");
  209. exit;
  210. }
  211. ?>