📄 gen_list.c
字号:
if(DB_UID&fil->attr) { fil->uid=fs.st_uid; }else { fil->uid=0; } if(DB_GID&fil->attr){ fil->gid=fs.st_gid; }else{ fil->gid=0; } if(DB_PERM&fil->attr){ fil->perm=fs.st_mode; }else{ fil->perm=0; } if(DB_SIZE&fil->attr||DB_SIZEG&fil->attr){ fil->size=fs.st_size; }else{ fil->size=0; } if(DB_LNKCOUNT&fil->attr){ fil->nlink=fs.st_nlink; }else { fil->nlink=0; } if(DB_MTIME&fil->attr){ fil->mtime=fs.st_mtime; }else{ fil->mtime=0; } if(DB_CTIME&fil->attr){ fil->ctime=fs.st_ctime; }else{ fil->ctime=0; } if(DB_ATIME&fil->attr){ fil->atime=fs.st_atime; }else{ fil->atime=0; } if(DB_BCOUNT&fil->attr){ fil->bcount=fs.st_blocks; } else { fil->bcount=0; }#ifdef WITH_ACL if(DB_ACL&fil->attr) { /* There might be a bug here. */ int res; fil->acl=malloc(sizeof(acl_type)); fil->acl->entries=acl(fil->filename,GETACLCNT,0,NULL); if (fil->acl->entries==-1) { char* er=strerror(errno); fil->acl->entries=0; if (er==NULL) { error(0,"ACL query failed for %s. strerror failed for %i\n",fil->filename,errno); } else { error(0,"ACL query failed for %s:%s\n",fil->filename,er); } } else { fil->acl->acl=malloc(sizeof(aclent_t)*fil->acl->entries); res=acl(fil->filename,GETACL,fil->acl->entries,fil->acl->acl); if (res==-1) { error(0,"ACL error %s\n",strerror(errno)); } else { if (res!=fil->acl->entries) { error(0,"Tried to read %i acl but got %i\n",fil->acl->entries,res); } } } }else{ fil->acl=NULL; }#endif if(S_ISDIR(fs.st_mode)||S_ISCHR(fs.st_mode) ||S_ISBLK(fs.st_mode)||S_ISFIFO(fs.st_mode) ||S_ISLNK(fs.st_mode)||S_ISSOCK(fs.st_mode)){ fil->attr&=(~DB_MD5)&(~DB_SHA1)&(~DB_RMD160)&(~DB_TIGER); fil->md5=NULL; fil->sha1=NULL; fil->tiger=NULL; fil->rmd160=NULL;#ifdef WITH_MHASH fil->attr&=(~DB_CRC32)&(~DB_HAVAL)&(~DB_CRC32B); fil->crc32=NULL; fil->crc32b=NULL; fil->haval=NULL; fil->gost=NULL;#endif }else { /* 1 if needs to be set * 0 otherwise */ fil->md5=DB_MD5&fil->attr?(byte*)"":NULL; fil->sha1=DB_SHA1&fil->attr?(byte*)"":NULL; fil->tiger=DB_TIGER&fil->attr?(byte*)"":NULL; fil->rmd160=DB_RMD160&fil->attr?(byte*)"":NULL;#ifdef WITH_MHASH fil->crc32=DB_CRC32&fil->attr?(byte*)"":NULL; fil->crc32b=DB_CRC32B&fil->attr?(byte*)"":NULL; fil->gost=DB_GOST&fil->attr?(byte*)"":NULL; fil->haval=DB_HAVAL&fil->attr?(byte*)"":NULL;#endif } listp=list_append(listp,(void*)fil); *addok=RETOK; return listp;}int check_list_for_match(list* rxrlist,char* text,int* attr){ list* r=NULL; int retval=1; for(r=rxrlist;r;r=r->next){ if((retval=regexec((regex_t*)((rx_rule*)r->data)->crx,text,0,0,0))==0){ *attr=((rx_rule*)r->data)->attr; error(231,"Matches rule from line #%ld: %s\n",((rx_rule*)r->data)->conf_lineno,((rx_rule*)r->data)->rx); break; } } return retval;}/* * Function check_node_for_match() * calls itself recursively to go to the top and then back down. * uses check_list_for_match() * returns: * 0, if a negative rule was matched * 1, if a selective rule was matched * 2, if a equals rule was matched * retval if no rule was matched. * retval&3 if no rule was matched and first in the recursion * */ int check_node_for_match(seltree*node,char*text,int retval,int* attr){ int top=0; if(node==NULL){ return retval; } /* We need this to check whether this was the first one * * to be called and not a recursive call */ if(!((retval&16)==16)){ retval|=16; top=1; } else{ top=0; } /* if no deeper match found */ if(!((retval&8)==8)&&!((retval&4)==4)){ if(!check_list_for_match(node->equ_rx_lst,text,attr)){ retval|=(2|4); }; }; /* We'll use retval to pass information on whether to recurse * the dir or not */ if(!((retval&8)==8)&&!((retval&4)==4)){ if(!check_list_for_match(node->sel_rx_lst,text,attr)) retval|=(1|8); } /* Now let's check the ancestors */ retval=check_node_for_match(node->parent,text,retval,attr); /* Negative regexps are the strongest so they are checked last */ /* If this file is to be added */ if(retval){ if(!check_list_for_match(node->neg_rx_lst,text,attr)){ retval=0; } } /* Now we discard the info whether a match was made or not * * and just return 0,1 or 2 */ if(top){ retval&=3; } return retval;}list* traverse_tree(seltree* tree,list* file_lst,int attr){ list* r=NULL; seltree* a=NULL; DIR* dirh=NULL; struct AIDE_DIRENT_TYPE* entp=NULL; struct AIDE_DIRENT_TYPE** resp=NULL; int rdres=0; int addfile=0; char* fullname=NULL; int e=0; int matchattr=attr;# ifndef HAVE_READDIR_R long td=-1;# endif int addok=RETOK; /* Root is special and it must be checked on it's own. */ if( tree->path[0]=='/' && tree->path[1]=='\0' ){ addfile=check_node_for_match(tree,"/",0,&matchattr); if(addfile){ error(240,"%s match=%d\n",fullname, addfile); file_lst=add_file_to_list(file_lst,"/",matchattr,&addok); } } if(!(dirh=opendir(tree->path))){ error(5,"traverse_tree():%s: %s\n", strerror(errno),tree->path); return file_lst; } # ifdef HAVE_READDIR_R resp=(struct AIDE_DIRENT_TYPE**) malloc(sizeof(struct AIDE_DIRENT_TYPE)+_POSIX_PATH_MAX); entp=(struct AIDE_DIRENT_TYPE*) malloc(sizeof(struct AIDE_DIRENT_TYPE)+_POSIX_PATH_MAX); for(rdres=AIDE_READDIR_R_FUNC(dirh,entp,resp); (rdres==0&&(*resp)!=NULL); rdres=AIDE_READDIR_R_FUNC(dirh,entp,resp)){# else# ifdef HAVE_READDIR for(entp=AIDE_READDIR_FUNC(dirh); (entp!=NULL&&td!=telldir(dirh)); entp=AIDE_READDIR_FUNC(dirh)){ td=telldir(dirh);# else# error AIDE needs readdir or readdir_r# endif# endif if(strncmp(entp->d_name,".",1)==0){ if(strncmp(entp->d_name,".",strlen(entp->d_name))==0) continue; if(strncmp(entp->d_name,"..",strlen(entp->d_name))==0) continue; } /* Construct fully qualified pathname for the file in question */ fullname=(char*) malloc(sizeof(char)*(strlen(entp->d_name)+strlen(tree->path)+2)); strncpy(fullname,tree->path,strlen(tree->path)); if(strncmp(tree->path,"/",strlen(tree->path))!=0){ strncpy(fullname+strlen(tree->path),"/",1); e=1; }else { e=0; } strncpy(fullname+strlen(tree->path)+e,entp->d_name,strlen(entp->d_name)); fullname[(strlen(tree->path)+e+strlen(entp->d_name))]='\0'; error(230,_("Checking %s for match\n"),fullname); if(attr){ /* This dir and all its subs are added by default */ addfile=1; addfile=check_node_for_match(tree,fullname,addfile,&matchattr); if(addfile){ error(240,"%s match=%d\n",fullname, addfile); file_lst=add_file_to_list(file_lst,fullname,matchattr,&addok); if( !(addfile&2) && addok!=RETFAIL){ if(S_ISDIR(((db_line*)file_lst->header->tail->data)->perm_o)){ a=get_seltree_node(tree, ((db_line*)file_lst->header->tail->data) ->filename); if(a==NULL){ a=new_seltree_node(tree, ((db_line*)file_lst->header->tail->data) ->filename,0,NULL); } file_lst=traverse_tree(a,file_lst,attr); } } } else { error(230,_("File %s does not match\n"),fullname); } } else{ /* This dir is not added by default */ addfile=0; addfile=check_node_for_match(tree,fullname,addfile,&matchattr); if(addfile){ error(240,"%s match=%d\n",fullname, addfile); file_lst=add_file_to_list(file_lst,fullname,matchattr,&addok); if(addfile!=2 && addok!=RETFAIL){ if(S_ISDIR(((db_line*)file_lst->header->tail->data)->perm_o)){ a=get_seltree_node(tree, ((db_line*)file_lst->header->tail->data) ->filename); if(a==NULL){ a=new_seltree_node(tree, ((db_line*)file_lst->header->tail->data) ->filename,0,NULL); } file_lst=traverse_tree(a,file_lst,matchattr); } } } else { error(230,_("File %s does not match\n"),fullname); } } free(fullname); } if(closedir(dirh)==-1){ error(0,"Closedir() failed for %s\n",tree->path); }; # ifdef HAVE_READDIR_R free(resp); free(entp);# endif /* All childs are not necessarily checked yet */ if(tree->childs!=NULL){ for(r=tree->childs;r;r=r->next){ if(!(((seltree*)r->data)->checked)) { file_lst=traverse_tree((seltree*)r->data,file_lst,attr); } } } tree->checked=1; return file_lst;}seltree* gen_tree(list* prxlist,list* nrxlist,list* erxlist){ seltree* tree=NULL; tree=new_seltree_node(NULL,"/",0,NULL); gen_seltree(prxlist,tree,'s'); gen_seltree(nrxlist,tree,'n'); gen_seltree(erxlist,tree,'e'); return tree;}list* gen_list(list* prxlist,list* nrxlist,list* erxlist){ list* r=NULL; seltree* tree=NULL; tree=gen_tree(prxlist,nrxlist,erxlist); if(tree==NULL){ return NULL; } r=traverse_tree(tree,NULL,0); return r;}/* * strip_dbline() * strips given dbline */void strip_dbline(db_line* line,int attr){#define checked_free(x) if(x!=NULL) free(x) /* filename is always needed, hence it is never stripped */ if(!(attr&DB_LINKNAME)){ checked_free(line->linkname); line->linkname=NULL; } if(!(attr&DB_PERM)){ line->perm=0; } if(!(attr&DB_UID)){ line->uid=0; } if(!(attr&DB_GID)){ line->gid=0; } if(!(attr&DB_ATIME)){ line->atime=0; } if(!(attr&DB_CTIME)){ line->ctime=0; } if(!(attr&DB_MTIME)){ line->mtime=0; } if(!(attr&DB_INODE)){ line->inode=0; } if(!(attr&DB_LNKCOUNT)){ line->nlink=0; } if(!(attr&DB_SIZE)){ line->size=0; } if(!(attr&DB_BCOUNT)){ line->bcount=0; } if(!(attr&DB_MD5)){ checked_free(line->md5); line->md5=NULL; } if(!(attr&DB_SHA1)){ checked_free(line->sha1); line->sha1=NULL; } if(!(attr&DB_RMD160)){ checked_free(line->rmd160); line->rmd160=NULL; } if(!(attr&DB_TIGER)){ checked_free(line->tiger); line->tiger=NULL; }#ifdef WITH_MHASH if(!(attr&DB_CRC32)){ checked_free(line->crc32); line->crc32=NULL; } if(!(attr&DB_CRC32B)){ checked_free(line->crc32b); line->crc32b=NULL; } if(!(attr&DB_GOST)){ checked_free(line->gost); line->gost=NULL; } if(!(attr&DB_HAVAL)){ checked_free(line->haval); line->haval=NULL; }#endif}/* * add_file_to_tree * db = which db this file belongs to * status = what to do with this node * attr attributes to add
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -