Date: Wed, 11 Nov 1998 19:37:25 +1100 From: "John Saunders" <john.saunders@scitec.com.au> To: "Oles' Hnatkevych" <gnut@uct.kiev.ua> Cc: <freebsd-questions@FreeBSD.ORG> Subject: RE: wtmp Message-ID: <004a01be0d4e$8200c010$6cb611cb@saruman.scitec.com.au> In-Reply-To: <Pine.BSF.4.02A.9811110927380.1062-100000@gw.uct.kiev.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
This is probably what you want. I have a collection of wtmp tools
I hacked up ages ago. Maybe I should make a formal release and a
port for it? :-)
cc zapwtmp.c -o zapwtmp
If you want to test it not on your main wtmp file...
cc -DDEBUG zapwtmp.c -o zapwtmp
cp /var/log/wtmp .
last -f wtmp | head -10
./zapwtmp ttyp0 fred host.com YYYYMMDDHHMM
last -f wtmp | head -10
I would also suggest using it during a quiet time as there is
an unavoidable race condition which may cause lost entries.
Although the wtmp file will not be corrupted.
Enjoy...
/*
* zapwtmp.c:
*
* Possible bugs.
*
* There is never any locking done on the wtmp file. I could have added file
* locking to this program, however it would not help as the other programs
* that write to wtmp do not have file locking either. This means there is a
* small window of possibility that a record can get lost. However this
window
* is much smaller than clnwtmp.c, and if used at a quiet period during the
* day will reduce the risk to almost 0%.
*
* Example use.
*
* zapwtmp ttyp1 fred host.com 199604131014
*/
#include <unistd.h>
#include <paths.h>
#include <fcntl.h>
#include <utmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*
* Make a copy of your wtmp file and play around with DEBUG enabled.
*/
#ifdef DEBUG
#undef _PATH_WTMP
#define _PATH_WTMP "wtmp"
#endif
static int convert_date(char *date_str, time_t *cvt_time);
int main(int argc, char **argv)
{
struct utmp wtmp;
time_t search_time;
time_t time_delta;
int fin, fout;
int searching = 0;
size_t length = 0;
if (argc != 5)
{
fprintf(stderr, "usage: %s port user host YYYYMMDDHHMM\n", argv[0]);
return (1);
}
if (! convert_date(argv[4], &search_time))
{
fprintf(stderr, "Invalid time \"%s\" (e.g. YYYYMMDDHHMM)\n", argv[4]);
return (1);
}
if ((fin = open(_PATH_WTMP, O_RDONLY)) < 0)
{
perror(_PATH_WTMP);
return (1);
}
if ((fout = open(_PATH_WTMP, O_WRONLY)) < 0)
{
perror(_PATH_WTMP);
close(fin);
return (1);
}
/*
* Read each wtmp record and sort based on the cutoff date.
*/
while (read(fin, &wtmp, sizeof(wtmp)) == sizeof(wtmp))
{
if (searching == 0)
{
time_delta = (search_time > wtmp.ut_time ?
search_time - wtmp.ut_time :
wtmp.ut_time - search_time);
/* Zap the login record */
if ((strncmp(wtmp.ut_line, argv[1], UT_LINESIZE) == 0) &&
(strncmp(wtmp.ut_name, argv[2], UT_NAMESIZE) == 0) &&
(strncmp(wtmp.ut_host, argv[3], UT_NAMESIZE) == 0) &&
(time_delta <= 60))
{
#ifdef DEBUG
printf("Found login record\n");
#endif
searching = 1;
}
else
{
write(fout, &wtmp, sizeof(wtmp));
length += sizeof(wtmp);
}
}
else if (searching == 1)
{
/* Zap the logout record */
if (strncmp(wtmp.ut_line, argv[1], UT_LINESIZE) == 0)
{
#ifdef DEBUG
printf("Found logout record\n");
#endif
searching = 2;
}
else
{
write(fout, &wtmp, sizeof(wtmp));
length += sizeof(wtmp);
}
}
else /* searching == 2 */
{
write(fout, &wtmp, sizeof(wtmp));
length += sizeof(wtmp);
}
}
/*
* The window mentioned in the bugs section is between the above
* read (insde the while loop) and this call to ftruncate.
*/
ftruncate(fout, length);
close(fout);
close(fin);
return (0);
}
/*
* Dipy date conversion. Hopefully it will be OK if it's not provided
* any "funny" dates.
*/
static int convert_date(char *date_str, time_t *cvt_time)
{
char string[5];
long date;
int year, month, day, hour, min;
struct tm cutdate;
string[4] = '\0';
string[0] = *date_str; if (*date_str) ++date_str;
string[1] = *date_str; if (*date_str) ++date_str;
string[2] = *date_str; if (*date_str) ++date_str;
string[3] = *date_str; if (*date_str) ++date_str;
year = atoi(string);
if (year < 1900)
{
return (0);
}
year -= 1900;
string[2] = '\0';
string[0] = *date_str; if (*date_str) ++date_str;
string[1] = *date_str; if (*date_str) ++date_str;
month = atoi(string);
if ((month < 1) || (month > 12))
{
return (0);
}
string[0] = *date_str; if (*date_str) ++date_str;
string[1] = *date_str; if (*date_str) ++date_str;
day = atoi(string);
if ((day < 1) || (day > 31))
{
return (0);
}
string[0] = *date_str; if (*date_str) ++date_str;
string[1] = *date_str; if (*date_str) ++date_str;
hour = atoi(string);
if (hour > 23)
{
return (0);
}
string[0] = *date_str; if (*date_str) ++date_str;
string[1] = *date_str; if (*date_str) ++date_str;
min = atoi(string);
if (min > 59)
{
return (0);
}
cutdate.tm_sec = 0;
cutdate.tm_min = min;
cutdate.tm_hour = hour;
cutdate.tm_mday = day;
cutdate.tm_mon = month - 1;
cutdate.tm_year = year;
cutdate.tm_isdst = -1;
/*
* Check that mktime didn't find any problems.
*/
if ((*cvt_time = mktime(&cutdate)) == (time_t)(-1))
{
return (0);
}
/*
* If the month has changed, that means mktime detected a
* day that is outside the allowable days for that month.
* i.e. you specified the 31st of February!
*/
if (cutdate.tm_mon != (month - 1))
{
return (0);
}
return (1);
}
-- . +-------------------------------------------------------+
,--_|\ | John Saunders mailto:John.Saunders@scitec.com.au |
/ Oz \ | SCITEC LIMITED Phone +61294289563 Fax +61294289933 |
\_,--\_/ | "By the time you make ends meet, they move the ends." |
v +-------------------------------------------------------+
> -----Original Message-----
> From: owner-freebsd-questions@FreeBSD.ORG
> [mailto:owner-freebsd-questions@FreeBSD.ORG]On Behalf Of Oles'
> Hnatkevych
> Sent: Wednesday, 11 November 1998 18:30
> To: Jason C. Wells
> Cc: freebsd-questions@FreeBSD.ORG
> Subject: Re: wtmp
>
>
> >
> > OK. You erased the wtmp file. You want to know if there is
> documentation.
> >
>
> No. I have the file. I just want to remove a record that user XXX
> logged in at the time A and logged out at the time B. To pretend that
> he never did.
>
>
> Best wishes,
>
> Oles Hnatkevych, http://gnut.kiev.ua
>
>
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-questions" in the body of the message
>
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?004a01be0d4e$8200c010$6cb611cb>
