📄 gen_list.c
字号:
/* aide, Advanced Intrusion Detection Environment * * Copyright (C) 1999,2000,2001,2002 Rami Lehti,Pablo Virolainen * $Header: /cvs-root-aide/aide2/src/gen_list.c,v 1.17 2002/05/30 09:53:52 pablo Exp $ * * 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 of the * License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <string.h>#include "aide.h"#include <assert.h>#include <stdlib.h>#include <dirent.h>#include <unistd.h>#include <limits.h>#include <sys/stat.h>#include <sys/types.h>#ifdef HAVE_USTAT#include <ustat.h>#endif#include <errno.h>#include <time.h>#include "report.h"#include "config.h"#include "gnu_regex.h"#include "list.h"#include "gen_list.h"#include "seltree.h"#include "db.h"#include "db_config.h"#include "compare_db.h"#include "commandconf.h"#include "report.h"/*for locale support*/#include "locale-aide.h"/*for locale support*/#define CLOCK_SKEW 5#ifdef WITH_MHASH#include <mhash.h>#endif/*#include <gcrypt.h>*/#include "md.h"void hsymlnk(db_line* line);void fs2db_line(struct AIDE_STAT_TYPE* fs,db_line* line);void calc_md(struct AIDE_STAT_TYPE* old_fs,db_line* line);void no_hash(db_line* line);char* strrxtok(char* rx){ char*p=NULL; int i=0; /* This assumes that the first character is a slash */ int lastslash=1; /* i=0 because we want to return at least the first slash */ for(i=1;i<strlen(rx);i++){ switch(rx[i]) { case '/': lastslash=i; break; case '(': case '^': case '$': case '*': case '.': case '[': /* FIXME: The '\\' character should be handled more gracefully. */ /* That is, if it is the only special character then */ /* The next character should be taken literally so */ /* that the search would be more efficient */ case '\\': i=strlen(rx); break; default: break; } } p=(char*)malloc(sizeof(char)*lastslash+1); strncpy(p,rx,lastslash); p[lastslash]='\0'; return p;}char* strlastslash(char*str){ char* p=NULL; int lastslash=1; int i=0; for(i=1;i<strlen(str);i++){ if(str[i]=='/'){ lastslash=i; } } p=(char*)malloc(sizeof(char)*lastslash+1); strncpy(p,str,lastslash); p[lastslash]='\0'; return p;}char* strgetndirname(char* path,int depth){ char* r=NULL; char* tmp=NULL; int i=0; for(r=path;;r+=1){ if(*r=='/') i++; if(*r=='\0') break; if(i==depth) break; } /* If we ran out string return the whole string */ if(!(*r)) return strdup(path); tmp=strdup(path); tmp[r-path]='\0'; return tmp;}int treedepth(seltree* node){ seltree* r=NULL; int depth=0; for(r=node;r;r=r->parent) depth++; return depth;}seltree* get_seltree_node(seltree* tree,char* path){ seltree* node=NULL; list* r=NULL; char* tmp=NULL; if(tree==NULL){ return NULL; } if(strncmp(path,tree->path,strlen(path)+1)==0){ return tree; } else{ tmp=strgetndirname(path,treedepth(tree)+1); for(r=tree->childs;r;r=r->next){ if(strncmp(((seltree*)r->data)->path,tmp,strlen(tmp)+1)==0){ node=get_seltree_node((seltree*)r->data,path); if(node!=NULL){ /* Don't leak memory */ free(tmp); return node; } } } free(tmp); } return NULL;}void copy_rule_ref(seltree* node, rx_rule* r){ if( r!=NULL ){ node->conf_lineno = r->conf_lineno; node->rx=(char*)malloc(strlen(r->rx)+1); strcpy(node->rx,r->rx); } else { node->conf_lineno = -1; node->rx=NULL; }}seltree* new_seltree_node( seltree* tree, char*path, int isrx, rx_rule* r){ seltree* node=NULL; seltree* parent=NULL; node=(seltree*)malloc(sizeof(seltree)); node->childs=NULL; node->path=strdup(path); node->sel_rx_lst=NULL; node->neg_rx_lst=NULL; node->equ_rx_lst=NULL; node->checked=0; node->attr=0; node->new_data=NULL; node->old_data=NULL; copy_rule_ref(node,r); if(tree!=NULL){ if(isrx){ parent=get_seltree_node(tree,strrxtok(path)); }else { parent=get_seltree_node(tree,strlastslash(path)); } if(parent==NULL){ if(isrx){ parent=new_seltree_node(tree,strrxtok(path),isrx,r); }else { parent=new_seltree_node(tree,strlastslash(path),isrx,r); } } parent->childs=list_append(parent->childs,(void*)node); node->parent=parent; }else { node->parent=NULL; } return node;}void gen_seltree(list* rxlist,seltree* tree,char type){ regex_t* rxtmp = NULL; seltree* curnode = NULL; list* r = NULL; char* rxtok = NULL; rx_rule* rxc = NULL; for(r=rxlist;r;r=r->next){ char* data; rx_rule* curr_rule = (rx_rule*)r->data; rxtok=strrxtok(curr_rule->rx); curnode=get_seltree_node(tree,rxtok); if(curnode==NULL){ curnode=new_seltree_node(tree,rxtok,1,curr_rule); } /* We have to add '^' to the first charaster of string... * */ data=(char*)malloc(strlen(curr_rule->rx)+1+1); if (data==NULL){ error(0,_("Not enough memory for regexpr compile... exiting..\n")); abort(); } /* FIX ME! (returnvalue) */ strcpy(data+1,curr_rule->rx); data[0]='^'; rxtmp=(regex_t*)malloc(sizeof(regex_t)); if( regcomp(rxtmp,data,REG_EXTENDED|REG_NOSUB)){ error(0,_("Error in selective regexp:%s"),curr_rule->rx); free(data); }else{ /* replace regexp text with regexp compiled */ rxc=(rx_rule*)malloc(sizeof(rx_rule)); rxc->rx=data; /* and copy the rest */ rxc->crx=rxtmp; rxc->attr=curr_rule->attr; rxc->conf_lineno=curr_rule->conf_lineno; switch (type){ case 's':{ curnode->sel_rx_lst=list_append(curnode->sel_rx_lst,(void*)rxc); break; } case 'n':{ curnode->neg_rx_lst=list_append(curnode->neg_rx_lst,(void*)rxc); break; } case 'e':{ curnode->equ_rx_lst=list_append(curnode->equ_rx_lst,(void*)rxc); break; } } } /* Data should not be free'ed because it's in rxc struct * and freeing is done if error occour. */ }}list* add_file_to_list(list* listp,char*filename,int attr,int* addok){ db_line* fil=NULL; time_t cur_time; struct AIDE_STAT_TYPE fs; int sres=0; error(220, _("Adding %s to filelist\n"),filename); fil=(db_line*)malloc(sizeof(db_line)); fil->attr=attr|DB_FILENAME|DB_LINKNAME; fil->filename=(char*)malloc(sizeof(char)*strlen(filename)+1); strncpy(fil->filename,filename,strlen(filename)); fil->filename[strlen(filename)]='\0'; /* We want to use lstat here instead of stat since we want * * symlinks stats not the file that it points to. */ sres=AIDE_LSTAT_FUNC(fil->filename,&fs); if(sres==-1){ char* er=strerror(errno); if (er==NULL) { error(0,"lstat() failed for %s. strerror failed for %i\n",fil->filename,errno); } else { error(0,"lstat() failed for %s:%s\n",fil->filename,strerror(errno)); } free(fil->filename); free(fil); *addok=RETFAIL; return listp; } cur_time=time(NULL); if (cur_time==(time_t)-1) { char* er=strerror(errno); if (er==NULL) { error(0,_("Can not get current time. strerror failed for %i\n"),errno); } else { error(0,_("Can not get current time with reason %s\n"),er); } } else { if(fs.st_atime>cur_time){ error(CLOCK_SKEW,_("%s atime in future\n"),fil->filename); } if(fs.st_mtime>cur_time){ error(CLOCK_SKEW,_("%s mtime in future\n"),fil->filename); } if(fs.st_ctime>cur_time){ error(CLOCK_SKEW,_("%s ctime in future\n"),fil->filename); } } #ifdef HAVE_USTAT /* Here we should check if we need to add it.. */ { struct ustat buf; if (ustat(fs.st_dev, &buf) != 0 || buf.f_fname[0]==0) { } else { } }#endif fil->perm_o=fs.st_mode; fil->size_o=fs.st_size; if((S_ISLNK(fs.st_mode))){ char* lnktmp=NULL; char* lnkbuf=NULL; int len=0; #ifdef WITH_ACL if(conf->no_acl_on_symlinks!=1) { fil->attr&=(~DB_ACL); }#endif if(conf->warn_dead_symlinks==1) { struct AIDE_STAT_TYPE fs; int sres; sres=AIDE_STAT_FUNC(fil->filename,&fs); if (sres!=0) { error(5,"Dead symlink detected at %s\n",fil->filename); } } if(conf->symlinks_found==0){ int it=0; DB_FIELD dbtmp; DB_FIELD dbtmp2; dbtmp=conf->db_out_order[1]; conf->db_out_order[1]=db_linkname; for(it=2;it<conf->db_out_size;it++){ dbtmp2=conf->db_out_order[it]; conf->db_out_order[it]=dbtmp; dbtmp=dbtmp2; } conf->db_out_order[conf->db_out_size++]=dbtmp; conf->symlinks_found=1; } lnktmp=(char*)malloc(_POSIX_PATH_MAX+1); if(lnktmp==NULL){ error(0,_("malloc failed in add_file_to_list()\n")); abort(); } len=readlink(fil->filename,lnktmp,_POSIX_PATH_MAX+1); if(len == -1){ error(0,"readlink failed in add_file_to_list(): %d,%s\n" ,errno,strerror(errno)); free(lnktmp); free(fil->filename); free(fil); *addok=RETFAIL; return listp; } lnkbuf=(char*)malloc(len+1); if(lnkbuf==NULL){ error(0,_("malloc failed in add_file_to_list()\n")); abort(); } strncpy(lnkbuf,lnktmp,len); lnkbuf[len]='\0'; fil->linkname=lnkbuf; free(lnktmp); fil->attr|=DB_LINKNAME; }else { fil->linkname=NULL; /* Just remove linkname avaivilibity bit from this entry */ fil->attr&=(~DB_LINKNAME); } if(DB_INODE&fil->attr){ fil->inode=fs.st_ino; } else { fil->inode=0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -