|
Packit Service |
5e8d2a |
/* aide, Advanced Intrusion Detection Environment
|
|
Packit Service |
5e8d2a |
* vi: ts=8 sw=8
|
|
Packit Service |
5e8d2a |
*
|
|
Packit Service |
5e8d2a |
* Copyright (C) 1999-2002,2004-2006,2009-2011,2013 Rami Lehti, Pablo
|
|
Packit Service |
5e8d2a |
* Virolainen, Mike Markley, Richard van den Berg, Hannes von Haugwitz
|
|
Packit Service |
5e8d2a |
* $Header$
|
|
Packit Service |
5e8d2a |
*
|
|
Packit Service |
5e8d2a |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
5e8d2a |
* modify it under the terms of the GNU General Public License as
|
|
Packit Service |
5e8d2a |
* published by the Free Software Foundation; either version 2 of the
|
|
Packit Service |
5e8d2a |
* License, or (at your option) any later version.
|
|
Packit Service |
5e8d2a |
*
|
|
Packit Service |
5e8d2a |
* This program is distributed in the hope that it will be useful, but
|
|
Packit Service |
5e8d2a |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
5e8d2a |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
5e8d2a |
* General Public License for more details.
|
|
Packit Service |
5e8d2a |
*
|
|
Packit Service |
5e8d2a |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
5e8d2a |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
5e8d2a |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit Service |
5e8d2a |
*/
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#include "aide.h"
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifndef _POSIX_C_SOURCE
|
|
Packit Service |
5e8d2a |
#define _POSIX_C_SOURCE 200112L
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#include <limits.h>
|
|
Packit Service |
5e8d2a |
#include <stdio.h>
|
|
Packit Service |
5e8d2a |
#include <stdlib.h>
|
|
Packit Service |
5e8d2a |
#include <string.h>
|
|
Packit Service |
5e8d2a |
#include <errno.h>
|
|
Packit Service |
5e8d2a |
#include <sys/types.h>
|
|
Packit Service |
5e8d2a |
#include <sys/stat.h>
|
|
Packit Service |
5e8d2a |
#include <fcntl.h>
|
|
Packit Service |
5e8d2a |
#include <unistd.h>
|
|
Packit Service |
5e8d2a |
#include <sys/mman.h>
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#include "md.h"
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#include "db_config.h"
|
|
Packit Service |
5e8d2a |
#include "do_md.h"
|
|
Packit Service |
5e8d2a |
#include "report.h"
|
|
Packit Service |
5e8d2a |
#include "list.h"
|
|
Packit Service |
5e8d2a |
/*for locale support*/
|
|
Packit Service |
5e8d2a |
#include "locale-aide.h"
|
|
Packit Service |
5e8d2a |
/*for locale support*/
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
/* This define should be somewhere else */
|
|
Packit Service |
5e8d2a |
#define READ_BLOCK_SIZE 16777216
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef WITH_MHASH
|
|
Packit Service |
5e8d2a |
#include <mhash.h>
|
|
Packit Service |
5e8d2a |
#endif /* WITH_MHASH */
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
/* Redhat 5.0 needs this */
|
|
Packit Service |
5e8d2a |
#ifdef HAVE_MMAP
|
|
Packit Service |
5e8d2a |
#ifndef MAP_FAILED
|
|
Packit Service |
5e8d2a |
#define MAP_FAILED (-1)
|
|
Packit Service |
5e8d2a |
#endif /* MAP_FAILED */
|
|
Packit Service |
5e8d2a |
#define MMAP_BLOCK_SIZE 16777216
|
|
Packit Service |
5e8d2a |
#endif /* HAVE_MMAP */
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
/*
|
|
Packit Service |
5e8d2a |
#include <gcrypt.h>
|
|
Packit Service |
5e8d2a |
*/
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef WITH_PRELINK
|
|
Packit Service |
5e8d2a |
#include <sys/wait.h>
|
|
Packit Service |
5e8d2a |
#include <gelf.h>
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
/*
|
|
Packit Service |
5e8d2a |
* Is file descriptor prelinked binary/library?
|
|
Packit Service |
5e8d2a |
* Return: 1(yes) / 0(no)
|
|
Packit Service |
5e8d2a |
*
|
|
Packit Service |
5e8d2a |
*/
|
|
Packit Service |
5e8d2a |
int is_prelinked(int fd) {
|
|
Packit Service |
5e8d2a |
Elf *elf = NULL;
|
|
Packit Service |
5e8d2a |
Elf_Scn *scn = NULL;
|
|
Packit Service |
5e8d2a |
Elf_Data *data = NULL;
|
|
Packit Service |
5e8d2a |
GElf_Ehdr ehdr;
|
|
Packit Service |
5e8d2a |
GElf_Shdr shdr;
|
|
Packit Service |
5e8d2a |
GElf_Dyn dyn;
|
|
Packit Service |
5e8d2a |
int bingo;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
(void) elf_version(EV_CURRENT);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if ((elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL
|
|
Packit Service |
5e8d2a |
|| elf_kind(elf) != ELF_K_ELF
|
|
Packit Service |
5e8d2a |
|| gelf_getehdr(elf, &ehdr) == NULL
|
|
Packit Service |
5e8d2a |
|| !(ehdr.e_type == ET_DYN || ehdr.e_type == ET_EXEC))
|
|
Packit Service |
5e8d2a |
return 0;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
bingo = 0;
|
|
Packit Service |
5e8d2a |
while (!bingo && (scn = elf_nextscn(elf, scn)) != NULL) {
|
|
Packit Service |
5e8d2a |
(void) gelf_getshdr(scn, &shdr);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if (shdr.sh_type != SHT_DYNAMIC)
|
|
Packit Service |
5e8d2a |
continue;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
while (!bingo && (data = elf_getdata (scn, data)) != NULL) {
|
|
Packit Service |
ea4ed9 |
int maxndx;
|
|
Packit Service |
5e8d2a |
int ndx;
|
|
Packit Service |
ea4ed9 |
|
|
Packit Service |
ea4ed9 |
if (shdr.sh_entsize != 0)
|
|
Packit Service |
ea4ed9 |
maxndx = data->d_size / shdr.sh_entsize;
|
|
Packit Service |
ea4ed9 |
else
|
|
Packit Service |
ea4ed9 |
continue;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
for (ndx = 0; ndx < maxndx; ++ndx) {
|
|
Packit Service |
5e8d2a |
(void) gelf_getdyn (data, ndx, &dyn);
|
|
Packit Service |
5e8d2a |
if (!(dyn.d_tag == DT_GNU_PRELINKED || dyn.d_tag == DT_GNU_LIBLIST))
|
|
Packit Service |
5e8d2a |
continue;
|
|
Packit Service |
5e8d2a |
bingo = 1;
|
|
Packit Service |
5e8d2a |
break;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
return bingo;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
/*
|
|
Packit Service |
5e8d2a |
* Open path via prelink -y, set fd
|
|
Packit Service |
5e8d2a |
* Return: 0 failure / > 0 success
|
|
Packit Service |
5e8d2a |
*
|
|
Packit Service |
5e8d2a |
*/
|
|
Packit Service |
5e8d2a |
pid_t open_prelinked(const char * path, int * fd) {
|
|
Packit Service |
5e8d2a |
const char *cmd = PRELINK_PATH;
|
|
Packit Service |
5e8d2a |
pid_t pid = 0;
|
|
Packit Service |
5e8d2a |
int pipes[2];
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
pipes[0] = pipes[1] = -1;
|
|
Packit Service |
5e8d2a |
if (pipe(pipes) < 0)
|
|
Packit Service |
5e8d2a |
return 0;
|
|
Packit Service |
5e8d2a |
pid = fork();
|
|
Packit Service |
5e8d2a |
switch (pid) {
|
|
Packit Service |
5e8d2a |
case 0:
|
|
Packit Service |
5e8d2a |
/* child */
|
|
Packit Service |
5e8d2a |
close(pipes[0]);
|
|
Packit Service |
5e8d2a |
dup2(pipes[1], STDOUT_FILENO);
|
|
Packit Service |
5e8d2a |
close(pipes[1]);
|
|
Packit Service |
5e8d2a |
unsetenv("MALLOC_CHECK_");
|
|
Packit Service |
5e8d2a |
execl(cmd, cmd, "--verify", path, (char *) NULL);
|
|
Packit Service |
5e8d2a |
exit(1);
|
|
Packit Service |
5e8d2a |
break;
|
|
Packit Service |
5e8d2a |
case -1:
|
|
Packit Service |
5e8d2a |
close(pipes[0]);
|
|
Packit Service |
5e8d2a |
close(pipes[1]);
|
|
Packit Service |
5e8d2a |
return 0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
/* parent */
|
|
Packit Service |
5e8d2a |
close(pipes[1]);
|
|
Packit Service |
5e8d2a |
*fd = pipes[0];
|
|
Packit Service |
5e8d2a |
return pid;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
void free_hashes(db_line* dl){
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#define free_hash(a) dl->a=NULL
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
free_hash(md5);
|
|
Packit Service |
5e8d2a |
free_hash(sha1);
|
|
Packit Service |
5e8d2a |
free_hash(rmd160);
|
|
Packit Service |
5e8d2a |
free_hash(tiger);
|
|
Packit Service |
5e8d2a |
#ifdef WITH_MHASH
|
|
Packit Service |
5e8d2a |
free_hash(crc32);
|
|
Packit Service |
5e8d2a |
free_hash(haval);
|
|
Packit Service |
5e8d2a |
free_hash(gost);
|
|
Packit Service |
5e8d2a |
free_hash(crc32b);
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
free_hash(sha256);
|
|
Packit Service |
5e8d2a |
free_hash(sha512);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
int stat_cmp(struct AIDE_STAT_TYPE* f1,struct AIDE_STAT_TYPE* f2) {
|
|
Packit Service |
5e8d2a |
if (f1==NULL || f2==NULL) {
|
|
Packit Service |
5e8d2a |
return RETFAIL;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#define stat_cmp_helper(n,n2) ((f1->n!=f2->n)*n2)
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
return (stat_cmp_helper(st_ino,DB_INODE)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_mode,DB_PERM)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_nlink,DB_LNKCOUNT)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_size,DB_SIZE)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_mtime,DB_MTIME)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_ctime,DB_CTIME)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_blocks,DB_BCOUNT)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_blksize,DB_BSIZE)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_rdev,DB_RDEV)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_gid,DB_GID)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_uid,DB_UID)|
|
|
Packit Service |
5e8d2a |
stat_cmp_helper(st_dev,DB_DEV));
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
void no_hash(db_line* line);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
void calc_md(struct AIDE_STAT_TYPE* old_fs,db_line* line) {
|
|
Packit Service |
5e8d2a |
/*
|
|
Packit Service |
5e8d2a |
We stat after opening just to make sure that the file
|
|
Packit Service |
5e8d2a |
from we are about to calculate the hash is the correct one,
|
|
Packit Service |
5e8d2a |
and we don't read from a pipe :)
|
|
Packit Service |
5e8d2a |
*/
|
|
Packit Service |
5e8d2a |
struct AIDE_STAT_TYPE fs;
|
|
Packit Service |
5e8d2a |
int stat_diff,filedes;
|
|
Packit Service |
5e8d2a |
#ifdef WITH_PRELINK
|
|
Packit Service |
5e8d2a |
pid_t pid;
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
error(255,"calc_md called\n");
|
|
Packit Service |
5e8d2a |
#ifdef _PARAMETER_CHECK_
|
|
Packit Service |
5e8d2a |
if (line==NULL) {
|
|
Packit Service |
5e8d2a |
abort();
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef HAVE_O_NOATIME
|
|
Packit Service |
5e8d2a |
filedes=open(line->fullpath,O_RDONLY|O_NOATIME);
|
|
Packit Service |
5e8d2a |
if(filedes<0)
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
filedes=open(line->fullpath,O_RDONLY);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if (filedes==-1) {
|
|
Packit Service |
5e8d2a |
char* er=strerror(errno);
|
|
Packit Service |
5e8d2a |
if (er!=NULL) {
|
|
Packit Service |
5e8d2a |
error(3,"do_md(): open() for %s failed: %s\n",
|
|
Packit Service |
5e8d2a |
line->fullpath,er);
|
|
Packit Service |
5e8d2a |
} else {
|
|
Packit Service |
5e8d2a |
error(3,"do_md(): open() for %s failed: %i\n",
|
|
Packit Service |
5e8d2a |
line->fullpath,errno);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
/*
|
|
Packit Service |
5e8d2a |
Nop. Cannot cal hashes. Mark it.
|
|
Packit Service |
5e8d2a |
*/
|
|
Packit Service |
5e8d2a |
no_hash(line);
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
c89282 |
AIDE_FSTAT_FUNC(filedes,&fs);
|
|
Packit Service |
5e8d2a |
if(!(line->attr&DB_RDEV))
|
|
Packit Service |
5e8d2a |
fs.st_rdev=0;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef HAVE_POSIX_FADVISE
|
|
Packit Service |
5e8d2a |
if (posix_fadvise(filedes,0,fs.st_size,POSIX_FADV_NOREUSE)!=0) {
|
|
Packit Service |
5e8d2a |
error(255,"posix_fadvise error %s\n",strerror(errno));
|
|
Packit Service |
5e8d2a |
} else {
|
|
Packit Service |
5e8d2a |
error(255,"posix_fadvise(%i,0,%li,POSIX_FADV_NOREUSE) ok\n",filedes,fs.st_size);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
if ((stat_diff=stat_cmp(&fs,old_fs))==RETOK) {
|
|
Packit Service |
5e8d2a |
/*
|
|
Packit Service |
5e8d2a |
Now we have a 'valid' filehandle to read from a file.
|
|
Packit Service |
5e8d2a |
*/
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef WITH_PRELINK
|
|
Packit Service |
5e8d2a |
/*
|
|
Packit Service |
5e8d2a |
* Let's take care of prelinked libraries/binaries
|
|
Packit Service |
5e8d2a |
*/
|
|
Packit Service |
5e8d2a |
pid=0;
|
|
Packit Service |
5e8d2a |
if ( is_prelinked(filedes) ) {
|
|
Packit Service |
5e8d2a |
close(filedes);
|
|
Packit Service |
5e8d2a |
pid = open_prelinked(line->fullpath, &filedes);
|
|
Packit Service |
5e8d2a |
if (pid == 0) {
|
|
Packit Service |
5e8d2a |
error(0, "Error on starting prelink undo\n");
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
off_t r_size=0;
|
|
Packit Service |
5e8d2a |
off_t size=0;
|
|
Packit Service |
5e8d2a |
char* buf;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
struct md_container mdc;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
mdc.todo_attr=line->attr;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if (init_md(&mdc)==RETOK) {
|
|
Packit Service |
5e8d2a |
#ifdef HAVE_MMAP
|
|
Packit Service |
5e8d2a |
#ifdef WITH_PRELINK
|
|
Packit Service |
5e8d2a |
if (pid == 0) {
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
off_t curpos=0;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
r_size=fs.st_size;
|
|
Packit Service |
5e8d2a |
/* in mmap branch r_size is used as size remaining */
|
|
Packit Service |
5e8d2a |
while(r_size>0){
|
|
Packit Service |
5e8d2a |
if(r_size
|
|
Packit Service |
5e8d2a |
#ifdef __hpux
|
|
Packit Service |
5e8d2a |
buf = mmap(0,r_size,PROT_READ,MAP_PRIVATE,filedes,curpos);
|
|
Packit Service |
5e8d2a |
#else
|
|
Packit Service |
5e8d2a |
buf = mmap(0,r_size,PROT_READ,MAP_SHARED,filedes,curpos);
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
curpos+=r_size;
|
|
Packit Service |
5e8d2a |
size=r_size;
|
|
Packit Service |
5e8d2a |
r_size=0;
|
|
Packit Service |
5e8d2a |
}else {
|
|
Packit Service |
5e8d2a |
#ifdef __hpux
|
|
Packit Service |
5e8d2a |
buf = mmap(0,MMAP_BLOCK_SIZE,PROT_READ,MAP_PRIVATE,filedes,curpos);
|
|
Packit Service |
5e8d2a |
#else
|
|
Packit Service |
5e8d2a |
buf = mmap(0,MMAP_BLOCK_SIZE,PROT_READ,MAP_SHARED,filedes,curpos);
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
curpos+=MMAP_BLOCK_SIZE;
|
|
Packit Service |
5e8d2a |
size=MMAP_BLOCK_SIZE;
|
|
Packit Service |
5e8d2a |
r_size-=MMAP_BLOCK_SIZE;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
if ( buf == MAP_FAILED ) {
|
|
Packit Service |
5e8d2a |
error(0,"error mmap'ing %s: %s\n", line->fullpath,strerror(errno));
|
|
Packit Service |
5e8d2a |
close(filedes);
|
|
Packit Service |
5e8d2a |
close_md(&mdc;;
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
conf->catch_mmap=1;
|
|
Packit Service |
5e8d2a |
if (update_md(&mdc,buf,size)!=RETOK) {
|
|
Packit Service |
5e8d2a |
error(0,"Message digest failed during update\n");
|
|
Packit Service |
5e8d2a |
close(filedes);
|
|
Packit Service |
5e8d2a |
close_md(&mdc;;
|
|
Packit Service |
5e8d2a |
munmap(buf,size);
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
munmap(buf,size);
|
|
Packit Service |
5e8d2a |
conf->catch_mmap=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
/* we have used MMAP, let's return */
|
|
Packit Service |
5e8d2a |
close_md(&mdc;;
|
|
Packit Service |
5e8d2a |
md2line(&mdc,line);
|
|
Packit Service |
5e8d2a |
close(filedes);
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
#ifdef WITH_PRELINK
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
#endif /* not HAVE_MMAP */
|
|
Packit Service |
c89282 |
// buf=malloc(READ_BLOCK_SIZE);
|
|
Packit Service |
5e8d2a |
#if READ_BLOCK_SIZE>SSIZE_MAX
|
|
Packit Service |
5e8d2a |
#error "READ_BLOCK_SIZE" is too large. Max value is SSIZE_MAX, and current is READ_BLOCK_SIZE
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
while ((size=TEMP_FAILURE_RETRY(read(filedes,buf,READ_BLOCK_SIZE)))>0) {
|
|
Packit Service |
5e8d2a |
if (update_md(&mdc,buf,size)!=RETOK) {
|
|
Packit Service |
5e8d2a |
error(0,"Message digest failed during update\n");
|
|
Packit Service |
5e8d2a |
close(filedes);
|
|
Packit Service |
5e8d2a |
close_md(&mdc;;
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
r_size+=size;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef WITH_PRELINK
|
|
Packit Service |
5e8d2a |
if (pid) {
|
|
Packit Service |
5e8d2a |
int status;
|
|
Packit Service |
5e8d2a |
(void) waitpid(pid, &status, 0);
|
|
Packit Service |
5e8d2a |
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
|
|
Packit Service |
5e8d2a |
error(0, "Error on exit of prelink child process\n");
|
|
Packit Service |
5e8d2a |
close(filedes);
|
|
Packit Service |
5e8d2a |
close_md(&mdc;;
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
free(buf);
|
|
Packit Service |
5e8d2a |
close_md(&mdc;;
|
|
Packit Service |
5e8d2a |
md2line(&mdc,line);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
} else {
|
|
Packit Service |
5e8d2a |
error(3,"Message digest initialization failed.\n");
|
|
Packit Service |
5e8d2a |
no_hash(line);
|
|
Packit Service |
5e8d2a |
close(filedes);
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
} else {
|
|
Packit Service |
5e8d2a |
unsigned i;
|
|
Packit Service |
5e8d2a |
/*
|
|
Packit Service |
5e8d2a |
Something just wasn't correct, so no hash calculated.
|
|
Packit Service |
5e8d2a |
*/
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
error(5,"Entry %s was changed so that hash cannot be calculated for it\n"
|
|
Packit Service |
5e8d2a |
,line->fullpath);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
for(i=0;i
|
|
Packit Service |
5e8d2a |
if (((1<
|
|
Packit Service |
5e8d2a |
error(5,"Attribute %s has been changed\n",db_names[i]);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
no_hash(line);
|
|
Packit Service |
5e8d2a |
close(filedes);
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
close(filedes);
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
void fs2db_line(struct AIDE_STAT_TYPE* fs,db_line* line) {
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
line->inode=fs->st_ino;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if(DB_UID&line->attr) {
|
|
Packit Service |
5e8d2a |
line->uid=fs->st_uid;
|
|
Packit Service |
5e8d2a |
}else {
|
|
Packit Service |
5e8d2a |
line->uid=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if(DB_GID&line->attr){
|
|
Packit Service |
5e8d2a |
line->gid=fs->st_gid;
|
|
Packit Service |
5e8d2a |
}else{
|
|
Packit Service |
5e8d2a |
line->gid=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
line->perm=fs->st_mode;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if(DB_SIZE&line->attr||DB_SIZEG&line->attr){
|
|
Packit Service |
5e8d2a |
line->size=fs->st_size;
|
|
Packit Service |
5e8d2a |
}else{
|
|
Packit Service |
5e8d2a |
line->size=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if(DB_LNKCOUNT&line->attr){
|
|
Packit Service |
5e8d2a |
line->nlink=fs->st_nlink;
|
|
Packit Service |
5e8d2a |
}else {
|
|
Packit Service |
5e8d2a |
line->nlink=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if(DB_MTIME&line->attr){
|
|
Packit Service |
5e8d2a |
line->mtime=fs->st_mtime;
|
|
Packit Service |
5e8d2a |
}else{
|
|
Packit Service |
5e8d2a |
line->mtime=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if(DB_CTIME&line->attr){
|
|
Packit Service |
5e8d2a |
line->ctime=fs->st_ctime;
|
|
Packit Service |
5e8d2a |
}else{
|
|
Packit Service |
5e8d2a |
line->ctime=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if(DB_ATIME&line->attr){
|
|
Packit Service |
5e8d2a |
line->atime=fs->st_atime;
|
|
Packit Service |
5e8d2a |
}else{
|
|
Packit Service |
5e8d2a |
line->atime=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if(DB_BCOUNT&line->attr){
|
|
Packit Service |
5e8d2a |
line->bcount=fs->st_blocks;
|
|
Packit Service |
5e8d2a |
} else {
|
|
Packit Service |
5e8d2a |
line->bcount=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef WITH_ACL
|
|
Packit Service |
5e8d2a |
void acl2line(db_line* line) {
|
|
Packit Service |
5e8d2a |
acl_type *ret = NULL;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef WITH_POSIX_ACL
|
|
Packit Service |
5e8d2a |
if(DB_ACL&line->attr) {
|
|
Packit Service |
5e8d2a |
acl_t acl_a;
|
|
Packit Service |
5e8d2a |
acl_t acl_d;
|
|
Packit Service |
5e8d2a |
char *tmp = NULL;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
acl_a = acl_get_file(line->fullpath, ACL_TYPE_ACCESS);
|
|
Packit Service |
5e8d2a |
acl_d = acl_get_file(line->fullpath, ACL_TYPE_DEFAULT);
|
|
Packit Service |
5e8d2a |
if ((acl_a == NULL) && (errno == ENOTSUP)) {
|
|
Packit Service |
5e8d2a |
line->attr&=(~DB_ACL);
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
if (acl_a == NULL)
|
|
Packit Service |
5e8d2a |
error(0, "Tried to read access ACL on %s but failed with: %s\n",
|
|
Packit Service |
5e8d2a |
line->fullpath, strerror(errno));
|
|
Packit Service |
5e8d2a |
if ((acl_d == NULL) && (errno != EACCES)) /* ignore DEFAULT on files */
|
|
Packit Service |
5e8d2a |
{
|
|
Packit Service |
5e8d2a |
acl_free(acl_a);
|
|
Packit Service |
5e8d2a |
error(0, "Tried to read default ACL on %s but failed with: %s\n",
|
|
Packit Service |
5e8d2a |
line->fullpath, strerror(errno));
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
/* assume memory allocs work, like rest of AIDE code... */
|
|
Packit Service |
5e8d2a |
ret = malloc(sizeof(acl_type));
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
/* use tmp, so free() can be called instead of acl_free() */
|
|
Packit Service |
5e8d2a |
tmp = acl_to_text(acl_a, NULL);
|
|
Packit Service |
5e8d2a |
if (!tmp || !*tmp)
|
|
Packit Service |
5e8d2a |
ret->acl_a = NULL;
|
|
Packit Service |
5e8d2a |
else
|
|
Packit Service |
5e8d2a |
ret->acl_a = strdup(tmp);
|
|
Packit Service |
5e8d2a |
acl_free(tmp);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if (!acl_d)
|
|
Packit Service |
5e8d2a |
ret->acl_d = NULL;
|
|
Packit Service |
5e8d2a |
else
|
|
Packit Service |
5e8d2a |
{
|
|
Packit Service |
5e8d2a |
tmp = acl_to_text(acl_d, NULL);
|
|
Packit Service |
5e8d2a |
if (!tmp || !*tmp)
|
|
Packit Service |
5e8d2a |
ret->acl_d = NULL;
|
|
Packit Service |
5e8d2a |
else
|
|
Packit Service |
5e8d2a |
ret->acl_d = strdup(tmp);
|
|
Packit Service |
5e8d2a |
acl_free(tmp);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
acl_free(acl_a);
|
|
Packit Service |
5e8d2a |
acl_free(acl_d);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
line->acl = ret;
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
#ifdef WITH_SUN_ACL
|
|
Packit Service |
5e8d2a |
if(DB_ACL&line->attr) { /* There might be a bug here. */
|
|
Packit Service |
5e8d2a |
int res;
|
|
Packit Service |
5e8d2a |
line->acl=malloc(sizeof(acl_type));
|
|
Packit Service |
5e8d2a |
line->acl->entries=acl(line->fullpath,GETACLCNT,0,NULL);
|
|
Packit Service |
5e8d2a |
if (line->acl->entries==-1) {
|
|
Packit Service |
5e8d2a |
char* er=strerror(errno);
|
|
Packit Service |
5e8d2a |
line->acl->entries=0;
|
|
Packit Service |
5e8d2a |
if (er==NULL) {
|
|
Packit Service |
5e8d2a |
error(0,"ACL query failed for %s. strerror failed for %i\n",line->fullpath,errno);
|
|
Packit Service |
5e8d2a |
} else {
|
|
Packit Service |
5e8d2a |
error(0,"ACL query failed for %s:%s\n",line->fullpath,er);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
} else {
|
|
Packit Service |
5e8d2a |
line->acl->acl=malloc(sizeof(aclent_t)*line->acl->entries);
|
|
Packit Service |
5e8d2a |
res=acl(line->fullpath,GETACL,line->acl->entries,line->acl->acl);
|
|
Packit Service |
5e8d2a |
if (res==-1) {
|
|
Packit Service |
5e8d2a |
error(0,"ACL error %s\n",strerror(errno));
|
|
Packit Service |
5e8d2a |
} else {
|
|
Packit Service |
5e8d2a |
if (res!=line->acl->entries) {
|
|
Packit Service |
5e8d2a |
error(0,"Tried to read %i acl but got %i\n",line->acl->entries,res);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
}else{
|
|
Packit Service |
5e8d2a |
line->acl=NULL;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef WITH_XATTR
|
|
Packit Service |
5e8d2a |
static xattrs_type *xattr_new(void) {
|
|
Packit Service |
5e8d2a |
xattrs_type *ret = NULL;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
ret = malloc(sizeof(xattrs_type));
|
|
Packit Service |
5e8d2a |
ret->num = 0;
|
|
Packit Service |
5e8d2a |
ret->sz = 2;
|
|
Packit Service |
5e8d2a |
ret->ents = malloc(sizeof(xattr_node) * ret->sz);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
return (ret);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
static void *xzmemdup(const void *ptr, size_t len) {
|
|
Packit Service |
5e8d2a |
/* always keeps a 0 at the end... */
|
|
Packit Service |
5e8d2a |
void *ret = NULL;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
ret = malloc(len+1);
|
|
Packit Service |
5e8d2a |
memcpy(ret, ptr, len);
|
|
Packit Service |
5e8d2a |
((char*)ret)[len] = 0;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
return (ret);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
static void xattr_add(xattrs_type *xattrs, const char *key, const char
|
|
Packit Service |
5e8d2a |
*val, size_t vsz) {
|
|
Packit Service |
5e8d2a |
if (xattrs->num >= xattrs->sz) {
|
|
Packit Service |
5e8d2a |
xattrs->sz <<= 1;
|
|
Packit Service |
5e8d2a |
xattrs->ents = realloc(xattrs->ents, sizeof(xattr_node) * xattrs->sz);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
xattrs->ents[xattrs->num].key = strdup(key);
|
|
Packit Service |
5e8d2a |
xattrs->ents[xattrs->num].val = xzmemdup(val, vsz);
|
|
Packit Service |
5e8d2a |
xattrs->ents[xattrs->num].vsz = vsz;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
xattrs->num += 1;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
void xattrs2line(db_line *line) {
|
|
Packit Service |
5e8d2a |
/* get all generic user xattrs. */
|
|
Packit Service |
5e8d2a |
xattrs_type *xattrs = NULL;
|
|
Packit Service |
5e8d2a |
static ssize_t xsz = 1024;
|
|
Packit Service |
5e8d2a |
static char *xatrs = NULL;
|
|
Packit Service |
5e8d2a |
ssize_t xret = -1;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if (!(DB_XATTRS&line->attr))
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
/* assume memory allocs work, like rest of AIDE code... */
|
|
Packit Service |
5e8d2a |
if (!xatrs) xatrs = malloc(xsz);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
while (((xret = llistxattr(line->fullpath, xatrs, xsz)) == -1) && (errno == ERANGE)) {
|
|
Packit Service |
5e8d2a |
xsz <<= 1;
|
|
Packit Service |
5e8d2a |
xatrs = realloc(xatrs, xsz);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if ((xret == -1) && ((errno == ENOSYS) || (errno == ENOTSUP))) {
|
|
Packit Service |
5e8d2a |
line->attr&=(~DB_XATTRS);
|
|
Packit Service |
5e8d2a |
} else if (xret == -1) {
|
|
Packit Service |
5e8d2a |
error(0, "listxattrs failed for %s:%s\n", line->fullpath, strerror(errno));
|
|
Packit Service |
5e8d2a |
} else if (xret) {
|
|
Packit Service |
5e8d2a |
const char *attr = xatrs;
|
|
Packit Service |
5e8d2a |
static ssize_t asz = 1024;
|
|
Packit Service |
5e8d2a |
static char *val = NULL;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if (!val) val = malloc(asz);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
xattrs = xattr_new();
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
while (xret > 0) {
|
|
Packit Service |
5e8d2a |
size_t len = strlen(attr);
|
|
Packit Service |
5e8d2a |
ssize_t aret = 0;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if (strncmp(attr, "user.", strlen("user.")) &&
|
|
Packit Service |
5e8d2a |
strncmp(attr, "root.", strlen("root.")))
|
|
Packit Service |
5e8d2a |
goto next_attr; /* only store normal xattrs, and SELinux */
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
while (((aret = getxattr(line->fullpath, attr, val, asz)) ==
|
|
Packit Service |
5e8d2a |
-1) && (errno == ERANGE)) {
|
|
Packit Service |
5e8d2a |
asz <<= 1;
|
|
Packit Service |
5e8d2a |
val = realloc (val, asz);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if (aret != -1)
|
|
Packit Service |
5e8d2a |
xattr_add(xattrs, attr, val, aret);
|
|
Packit Service |
5e8d2a |
else if (errno != ENOATTR)
|
|
Packit Service |
5e8d2a |
error(0, "getxattr failed for %s:%s\n", line->fullpath, strerror(errno));
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
next_attr:
|
|
Packit Service |
5e8d2a |
attr += len + 1;
|
|
Packit Service |
5e8d2a |
xret -= len + 1;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
line->xattrs = xattrs;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef WITH_SELINUX
|
|
Packit Service |
5e8d2a |
void selinux2line(db_line *line) {
|
|
Packit Service |
5e8d2a |
char *cntx = NULL;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if (!(DB_SELINUX&line->attr))
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
if (lgetfilecon_raw(line->fullpath, &cntx) == -1) {
|
|
Packit Service |
5e8d2a |
line->attr&=(~DB_SELINUX);
|
|
Packit Service |
5e8d2a |
if ((errno != ENOATTR) && (errno != EOPNOTSUPP))
|
|
Packit Service |
5e8d2a |
error(0, "lgetfilecon_raw failed for %s:%s\n", line->fullpath, strerror(errno));
|
|
Packit Service |
5e8d2a |
return;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
line->cntx = strdup(cntx);
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
freecon(cntx);
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
#ifdef WITH_E2FSATTRS
|
|
Packit Service |
5e8d2a |
void e2fsattrs2line(db_line* line) {
|
|
Packit Service |
5e8d2a |
unsigned long flags;
|
|
Packit Service |
5e8d2a |
if (DB_E2FSATTRS&line->attr) {
|
|
Packit Service |
5e8d2a |
if (fgetflags(line->fullpath, &flags) == 0) {
|
|
Packit Service |
5e8d2a |
line->e2fsattrs=flags;
|
|
Packit Service |
5e8d2a |
} else {
|
|
Packit Service |
5e8d2a |
line->attr&=(~DB_E2FSATTRS);
|
|
Packit Service |
5e8d2a |
line->e2fsattrs=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
} else {
|
|
Packit Service |
5e8d2a |
line->e2fsattrs=0;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
#endif
|
|
Packit Service |
5e8d2a |
|
|
Packit Service |
5e8d2a |
void no_hash(db_line* line) {
|
|
Packit Service |
5e8d2a |
line->attr&=~DB_HASHES;
|
|
Packit Service |
5e8d2a |
}
|
|
Packit Service |
5e8d2a |
|