3 /**********************************************************************************
4 ** (c) Copyright 2002, Brenno J.S.A.A.F. de Winter, De Winter Information Solutions
5 ** This is free software; you can redistribute it and/or modify it under the
6 ** terms of the GNU General Public License, see the file COPYING.
7 ***********************************************************************************/
13 Andromeda Technology & Automation
15 $Log: gcm_maintenance.php,v $
16 Revision 1.2 2011-03-24 09:49:20 arjen
17 Cleanup abuse records only for subnets smaller than /16.
19 Revision 1.1 2007/12/12 09:06:21 arjen
20 Added a new script gcm_maintenance.php to cleanup the database
21 and check referential integrity. Purging old log entries is
22 removed from the gcm_daemon script.
27 // $Id: gcm_maintenance.php,v 1.2 2011-03-24 09:49:20 arjen Exp $
29 ini_set('include_path', '.:./classes:../phpclasses');
30 ini_set('html_errors', 'false');
32 define("BATCHSIZE", 10000);
34 //Tell the log that we're up.
35 define_syslog_variables();
37 require_once "gnucomo_config.php";
38 require_once "db.class.php";
40 // Set the standard variables //
42 $purge_date =""; // Purge log entries until this date. Default: no purging
43 $project_name = "gnucomo"; // name of the entire project
44 $app_name = "gcm_maintenance"; // name of the application running
46 //Avoid time-limit issues
49 // Scan the command arguments
51 for ($argi = 1; $argi < $argc; $argi++)
57 $project_name = $argv[$argi];
62 $purge_date = $argv[$argi];
66 echo "Usage: gcm_daemon [-c configname] [-p purgedate]\n";
72 // Read the database settings //
73 $class_settings = new gnucomo_config();
74 if (!$class_settings->read($project_name))
76 echo "Can not read Gnucomo configuration file for $project_name.\n";
80 openlog("gnucomo", LOG_PID, LOG_DAEMON);
82 //Open an connection to the database
83 $dbms_type = $class_settings->find_parameter("database", "type");
84 $dbms_host = $class_settings->find_parameter("database", "host");
85 $dbms_name = $class_settings->find_parameter("database", "name");
86 $dbms_user = $class_settings->find_parameter("gcm_daemon", "user");
87 $dbms_password = $class_settings->find_parameter("gcm_daemon", "password");
89 db_select($dbms_type);
91 $dbms->db_host = $dbms_host;
92 $dbms->db_name = $dbms_name;
93 $dbms->db_user = $dbms_user;
94 $dbms->db_password = $dbms_password;
95 $dbms->db_connect($class_settings->database());
97 if ($dbms->have_db_connection() == "FALSE")
99 exit ("Database connection failed.");
102 if ($purge_date != "")
104 purge_old_logs($purge_date);
107 // Check the references from the abuse list to the logs
110 $abuse_result = $dbms->query("select source, nr_abuses, masklen(source) from object_abuse
111 where (status='dropped' or status='') and masklen(source)>16 and objectid=11 order by source");
112 for ($ab = 0; $ab < $dbms->num_rows($abuse_result); $ab++)
115 $abuse = $dbms->fetch_object($abuse_result, $ab);
116 $nr_abuses = $abuse->nr_abuses;
117 $log_res = $dbms->query("select logid from log_abuse where source='" . $abuse->source . "' and objectid=11");
119 if ($dbms->num_rows($log_res) != $nr_abuses)
121 echo "Mismatch in nr of abuses. Corrected.\n";
122 $dbms->query("update object_abuse set nr_abuses=" . $dbms->num_rows($log_res) .
123 " where source='" . $abuse->source . "' and objectid=11");
125 if ($dbms->num_rows($log_res) == 0)
127 echo " Removing ", $abuse->source, "\n";
128 $dbms->query("delete from object_abuse where source='". $abuse->source . "' and objectid=11");
132 $logref_res = $dbms->query("select logid from log where logid in
133 (select logid from log_abuse where source='" . $abuse->source . "' and objectid=11)");
134 $logentries = $dbms->num_rows($logref_res);
135 if ($logentries == 0)
137 echo "All references to log entries are lost. Purging log_abuse table.\n";
138 $dbms->query("delete from log_abuse where source='" . $abuse->source . "' and objectid=11");
142 echo $abuse->source . "\t$nr_abuses\t" . $dbms->num_rows($log_res) . "\t" . $logentries . "\n";
145 // Gather the statistics for each object
147 $obj_result = $dbms->query("SELECT objectid FROM object");
148 for ($obj = 0; $obj < $dbms->num_rows($obj_result); $obj++)
150 $object = $dbms->fetch_object($obj_result, $obj);
151 echo "Gathering statistics for object " . $object->objectid . "\n";
152 GatherStatistics($object->objectid);
156 function purge_old_logs($purge_date)
161 * Make a temporary table with the logids of the old log entries
162 * We don't want to repeat a selection on the large log table itself.
165 echo "Purging log entries before $purge_date\n";
167 $dbms->query("CREATE TABLE gcm_deamon_old_log AS SELECT logid FROM log WHERE timestamp < '$purge_date'");
168 $dbms->query("SELECT logid FROM gcm_deamon_old_log");
169 echo $dbms->num_rows() . " log entries found.\n";
171 // Clean up notifications that are left without reference to the log.
173 $r = $dbms->query("select notificationid from log_notification where logid in
174 (select logid from gcm_deamon_old_log) group by notificationid");
175 echo "Notifications that may be affected:\n";
176 $notifications = array();
177 for ($i=0; $i < $dbms->num_rows(); $i++)
179 $notif = $dbms->fetch_object($r, $i);
180 $notifications[] = $notif->notificationid;
181 echo $notif->notificationid . "\n";
183 $dbms->query("delete from log_notification where logid in
184 (select logid from gcm_deamon_old_log)");
186 // Clean up any notifications that have no more logs left
187 foreach ($notifications as $notif)
189 $c = $dbms->fetch_object($dbms->query("select count(*) from log_notification where notificationid=$notif"), 0);
190 echo "Notification $notif has " . $c->count . " log entries left.\n";
193 echo "Cleaning up notification $notif.\n";
194 $dbms->query("delete from action_user where notificationid=$notif");
195 $dbms->query("delete from notification where notificationid=$notif");
199 // Clean up abuses that are left without reference to the log.
201 $r = $dbms->query("select source from log_abuse where masklen(source) > 16 and logid in
202 (select logid from gcm_deamon_old_log) group by source");
203 echo "Abusing IP addresses that may be affected:\n";
205 for ($i = 0; $i < $dbms->num_rows(); $i++)
207 $ab = $dbms->fetch_object($r, $i);
208 $abusers[] = $ab->source;
209 echo $ab->source . "\n";
211 $dbms->query("delete from log_abuse where logid in
212 (select logid from gcm_deamon_old_log)");
214 foreach ($abusers as $src)
216 $c = $dbms->fetch_object($dbms->query("select count(*) from log_abuse where source='$src'"), 0);
217 echo "IP address $src has " . $c->count . " log entries left.\n";
220 echo "Cleaning up abusing address $src.\n";
221 $dbms->query("delete from object_abuse where source='$src' and (status='' or status='dropped')");
225 $dbms->query("delete from log where logid in
226 (select logid from gcm_deamon_old_log)");
228 $dbms->query("drop table gcm_deamon_old_log");
233 * Update a single statistic for some object.
234 * If it does not yet exist, it will be created.
237 function UpdateStatistic($objectid, $name, $value)
241 $result = $dbms->query("SELECT objectid FROM object_statistics WHERE
242 objectid='$objectid' AND statname='$name'");
243 if ($dbms->num_rows() == 0)
245 $dbms->query("INSERT INTO object_statistics VALUES
246 ('$objectid', '$name', '$value')");
250 $dbms->query("UPDATE object_statistics SET statvalue='$value' WHERE
251 statname='$name' AND objectid='$objectid'");
256 * Gather the statistics for a single object ($objectid).
257 * We count the number of parameters, removed parameters, notifications
258 * closed notifications and log entries. The totals of these are
259 * maintained in a separate table: object_statistics.
262 function GatherStatistics($objectid)
266 // Gather statistics on parameters
268 $r = $dbms->query("SELECT paramid FROM parameter WHERE objectid=CAST('"
269 . $objectid . "' AS BIGINT)");
270 $nr_parameters = $dbms->num_rows($r);
272 $removed_parameters = 0;
273 for ($p = 0; $p < $nr_parameters; $p++)
275 $param = pg_fetch_object($r, $p);
276 $qry ="select change_nature from history where paramid= CAST('";
277 $qry .= $param->paramid . "' AS BIGINT) order by modified desc";
278 $rhist = $dbms->query($qry);
279 if ($dbms->num_rows($rhist) == 0)
281 echo "ERROR: No history for parameter id " . $param->paramid . "\n";
285 $hist = $dbms->fetch_object($rhist, 0);
286 if ($hist->change_nature == "REMOVED")
288 $removed_parameters++;
293 UpdateStatistic($objectid, 'parameters', $nr_parameters);
294 UpdateStatistic($objectid, 'removed_parameters', $removed_parameters);
296 // Gather statistics on notifications
298 $r = $dbms->query("SELECT count(notificationid) FROM notification WHERE
299 objectid = CAST('" . $objectid . "' AS BIGINT)");
300 $cnt = $dbms->fetch_object($r, 0);
301 UpdateStatistic($objectid, 'notifications', $cnt->count);
303 $r = $dbms->query("SELECT count(notificationid) FROM notification WHERE
304 objectid = CAST('" . $objectid . "' AS BIGINT) AND statuscode ='cls'");
305 $cnt = $dbms->fetch_object($r, 0);
306 UpdateStatistic($objectid, 'closed_notifications', $cnt->count);
308 // Gather statistics on log entries
310 $r = $dbms->query("SELECT count(logid) FROM log WHERE
311 objectid = CAST('" . $objectid . "' AS BIGINT)");
312 $cnt = $dbms->fetch_object($r, 0);
313 UpdateStatistic($objectid, 'logs', $cnt->count);