Blame src/compare_db.c

Packit Service 5e8d2a
/* aide, Advanced Intrusion Detection Environment
Packit Service 5e8d2a
 *
Packit Service 5e8d2a
 * Copyright (C) 1999-2007,2010-2013,2015,2016 Rami Lehti, Pablo Virolainen,
Packit Service 5e8d2a
 * Richard van den Berg, Mike Markley, Hannes von Haugwitz
Packit Service 5e8d2a
 * $Id$
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
#include <stdlib.h>
Packit Service 5e8d2a
#include <string.h>
Packit Service 5e8d2a
#include <time.h>
Packit Service 5e8d2a
#include <sys/stat.h>
Packit Service 5e8d2a
#include <math.h>
Packit Service 5e8d2a
#ifdef WITH_AUDIT
Packit Service 5e8d2a
#include <libaudit.h>
Packit Service 5e8d2a
#ifdef HAVE_SYSLOG
Packit Service 5e8d2a
#include <syslog.h>
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
Packit Service 5e8d2a
#include "base64.h"
Packit Service 5e8d2a
#include "report.h"
Packit Service 5e8d2a
#include "db_config.h"
Packit Service 5e8d2a
#include "gen_list.h"
Packit Service 5e8d2a
#include "list.h"
Packit Service 5e8d2a
#include "db.h"
Packit Service 5e8d2a
#include "util.h"
Packit Service 5e8d2a
#include "commandconf.h"
Packit Service 5e8d2a
#include "gen_list.h"
Packit Service 5e8d2a
#include "compare_db.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
#include "md.h"
Packit Service 5e8d2a
Packit Service 5e8d2a
/*************/
Packit Service 5e8d2a
/* construction area for report lines */
Packit Service 5e8d2a
Packit Service 5e8d2a
const int width_details = 80;
Packit Service 5e8d2a
Packit Service 5e8d2a
const char time_format[] = "%Y-%m-%d %H:%M:%S %z";
Packit Service 5e8d2a
const int time_string_len = 26;
Packit Service 5e8d2a
Packit Service 5e8d2a
long ntotal, nadd, nrem, nchg = 0;
Packit Service 5e8d2a
Packit Service 5e8d2a
const char* report_top_format = "\n\n---------------------------------------------------\n%s:\n---------------------------------------------------\n";
Packit Service 5e8d2a
Packit Service 5e8d2a
DB_ATTR_TYPE ignored_added_attrs, ignored_removed_attrs, ignored_changed_attrs, forced_attrs;
Packit Service 5e8d2a
Packit Service 5e8d2a
const DB_ATTR_TYPE summary_attributes[] = { DB_FTYPE, DB_LINKNAME, DB_SIZE|DB_SIZEG, DB_BCOUNT, DB_PERM, DB_UID, DB_GID, DB_ATIME, DB_MTIME, DB_CTIME, DB_INODE, DB_LNKCOUNT, DB_HASHES
Packit Service 5e8d2a
#ifdef WITH_ACL
Packit Service 5e8d2a
        , DB_ACL
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_XATTR
Packit Service 5e8d2a
        , DB_XATTRS
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_SELINUX
Packit Service 5e8d2a
        , DB_SELINUX
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_E2FSATTRS
Packit Service 5e8d2a
        , DB_E2FSATTRS
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
};
Packit Service 5e8d2a
Packit Service 5e8d2a
const char summary_char[] = { '!' ,'l', '>', 'b', 'p', 'u', 'g', 'a', 'm', 'c', 'i', 'n', 'C'
Packit Service 5e8d2a
#ifdef WITH_ACL
Packit Service 5e8d2a
    , 'A'
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_XATTR
Packit Service 5e8d2a
    , 'X'
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_SELINUX
Packit Service 5e8d2a
    , 'S'
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_E2FSATTRS
Packit Service 5e8d2a
    , 'E'
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
};
Packit Service 5e8d2a
Packit Service 5e8d2a
const DB_ATTR_TYPE details_attributes[] = { DB_FTYPE, DB_LINKNAME, DB_SIZE, DB_SIZEG, DB_BCOUNT, DB_PERM, DB_UID, DB_GID, DB_ATIME, DB_MTIME, DB_CTIME, DB_INODE, DB_LNKCOUNT, DB_MD5, DB_SHA1, DB_RMD160, DB_TIGER, DB_SHA256, DB_SHA512
Packit Service 5e8d2a
#ifdef WITH_MHASH
Packit Service 5e8d2a
    , DB_CRC32, DB_HAVAL, DB_GOST, DB_CRC32B, DB_WHIRLPOOL
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_ACL
Packit Service 5e8d2a
        , DB_ACL
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_XATTR
Packit Service 5e8d2a
        , DB_XATTRS
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_SELINUX
Packit Service 5e8d2a
        , DB_SELINUX
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_E2FSATTRS
Packit Service 5e8d2a
        , DB_E2FSATTRS
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
};
Packit Service 5e8d2a
Packit Service 57cbf7
const char* details_string[] = { _("File type") , _("Lname"), _("Size"), _("Size"), _("Bcount"), _("Perm"), _("Uid"), _("Gid"), _("Atime"), _("Mtime"), _("Ctime"), _("Inode"), _("Linkcount"), _("MD5"), _("SHA1"), _("RMD160"), _("TIGER"), _("SHA256"), _("SHA512")
Packit Service 5e8d2a
#ifdef WITH_MHASH
Packit Service 5e8d2a
    , _("CRC32"), _("HAVAL"), _("GOST"), _("CRC32B"), _("WHIRLPOOL")
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_ACL
Packit Service 5e8d2a
    , _("ACL")
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_XATTR
Packit Service 5e8d2a
    , _("XAttrs")
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_SELINUX
Packit Service 5e8d2a
    , _("SELinux")
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_E2FSATTRS
Packit Service 5e8d2a
    , _("E2FSAttrs")
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
};
Packit Service 5e8d2a
Packit Service 5e8d2a
const char* attrs_string[] = { "filename", "l", "p", "u", "g", "s", "a", "c", "m", "i", "b", "n",
Packit Service 5e8d2a
                               "md5", "sha1", "rmd160", "tiger", "crc32", "haval", "gost", "crc32b",
Packit Service 5e8d2a
                               "attr", "acl", "bsize", "rdev", "dev", "checkmask", "S", "I", "ANF",
Packit Service 5e8d2a
                               "ARF", "sha256", "sha512", "selinux", "xattrs", "whirlpool", "ftype",
Packit Service 5e8d2a
                               "e2fsattrs" };
Packit Service 5e8d2a
Packit Service 5e8d2a
#ifdef WITH_E2FSATTRS
Packit Service 5e8d2a
    /* flag->character mappings taken from lib/e2p/pf.c (git commit c46b57b)
Packit Service 5e8d2a
     * date: 2015-05-10
Packit Service 5e8d2a
     * sources: git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
Packit Service 5e8d2a
     *
Packit Service 5e8d2a
     * on update see also do_e2fsattrs in commandconf.c
Packit Service 5e8d2a
     */
Packit Service 5e8d2a
    unsigned long flag_bits[] = { EXT2_SECRM_FL, EXT2_UNRM_FL, EXT2_SYNC_FL, EXT2_DIRSYNC_FL, EXT2_IMMUTABLE_FL,
Packit Service 5e8d2a
        EXT2_APPEND_FL, EXT2_NODUMP_FL, EXT2_NOATIME_FL, EXT2_COMPR_FL, EXT2_COMPRBLK_FL,
Packit Service 5e8d2a
        EXT2_DIRTY_FL, EXT2_NOCOMPR_FL,
Packit Service 5e8d2a
#ifdef EXT2_ECOMPR_FL
Packit Service 5e8d2a
        EXT2_ECOMPR_FL,
Packit Service 5e8d2a
#else
Packit Service 5e8d2a
        EXT4_ENCRYPT_FL,
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
        EXT3_JOURNAL_DATA_FL, EXT2_INDEX_FL,
Packit Service 5e8d2a
        EXT2_NOTAIL_FL, EXT2_TOPDIR_FL
Packit Service 5e8d2a
#ifdef EXT4_EXTENTS_FL
Packit Service 5e8d2a
        , EXT4_EXTENTS_FL
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef EXT4_HUGE_FILE_FL
Packit Service 5e8d2a
        , EXT4_HUGE_FILE_FL
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef FS_NOCOW_FL
Packit Service 5e8d2a
    , FS_NOCOW_FL
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef EXT4_INLINE_DATA_FL
Packit Service 5e8d2a
    , EXT4_INLINE_DATA_FL
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
Packit Service 5e8d2a
    };
Packit Service 5e8d2a
    char flag_char[] = { 's', 'u', 'S', 'D', 'i', 'a', 'd', 'A', 'c', 'B', 'Z', 'X', 'E', 'j', 'I', 't', 'T'
Packit Service 5e8d2a
#ifdef EXT4_EXTENTS_FL
Packit Service 5e8d2a
    , 'e'
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef EXT4_HUGE_FILE_FL
Packit Service 5e8d2a
    , 'h'
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef FS_NOCOW_FL
Packit Service 5e8d2a
    , 'C'
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef EXT4_INLINE_DATA_FL
Packit Service 5e8d2a
    , 'N'
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
    };
Packit Service 5e8d2a
/*************/
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
Packit Service 5e8d2a
static DB_ATTR_TYPE get_special_report_group(char* group) {
Packit Service 5e8d2a
    DB_ATTR_TYPE attr = get_groupval(group);
Packit Service 5e8d2a
    return attr==DB_ATTR_UNDEF?0:attr;
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static char* report_attrs(DB_ATTR_TYPE attrs) {
Packit Service 5e8d2a
    char* str;
Packit Service 5e8d2a
    int j = 1;
Packit Service 5e8d2a
    int num_attrs = sizeof(attrs_string)/sizeof(char*);
Packit Service 5e8d2a
    for (int i = 0; i < num_attrs; ++i) {
Packit Service 5e8d2a
        if ((1LLU<
Packit Service 5e8d2a
            j += strlen(attrs_string[i])+1;
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    str = malloc(j * sizeof (char));
Packit Service 5e8d2a
    j=0;
Packit Service 5e8d2a
    for (int i = 0; i < num_attrs; ++i) {
Packit Service 5e8d2a
        if ((1LLU<
Packit Service 5e8d2a
            if (j) { str[j++] = '+'; }
Packit Service 5e8d2a
            j += sprintf(&str[j], "%s", attrs_string[i]);
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    str[j] = '\0';
Packit Service 5e8d2a
    return str;
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static char get_file_type_char(mode_t mode) {
Packit Service 5e8d2a
    switch (mode & S_IFMT) {
Packit Service 5e8d2a
        case S_IFREG: return 'f';
Packit Service 5e8d2a
        case S_IFDIR: return 'd';
Packit Service 5e8d2a
#ifdef S_IFIFO
Packit Service 5e8d2a
        case S_IFIFO: return 'p';
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
        case S_IFLNK: return 'l';
Packit Service 5e8d2a
        case S_IFBLK: return 'b';
Packit Service 5e8d2a
        case S_IFCHR: return 'c';
Packit Service 5e8d2a
#ifdef S_IFSOCK
Packit Service 5e8d2a
        case S_IFSOCK: return 's';
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef S_IFDOOR
Packit Service 5e8d2a
        case S_IFDOOR: return 'D';
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef S_IFPORT
Packit Service 5e8d2a
        case S_IFPORT: return 'P';
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
        default: return '?';
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
Packit Service 5e8d2a
Packit Service 5e8d2a
#ifdef WITH_XATTR
Packit Service 5e8d2a
static size_t xstrnspn(const char *s1, size_t len, const char *srch)
Packit Service 5e8d2a
{
Packit Service 5e8d2a
  const char *os1 = s1;
Packit Service 5e8d2a
  
Packit Service 5e8d2a
  while (len-- && strchr(srch, *s1))
Packit Service 5e8d2a
    ++s1;
Packit Service 5e8d2a
Packit Service 5e8d2a
  return (s1 - os1);
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
#define PRINTABLE_XATTR_VALS                    \
Packit Service 5e8d2a
    "0123456789"                                \
Packit Service 5e8d2a
    "abcdefghijklmnopqrstuvwxyz"                \
Packit Service 5e8d2a
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"                \
Packit Service 5e8d2a
    ".-_:;,[]{}<>()!@#$%^&*|\\/?~"
Packit Service 5e8d2a
Packit Service 5e8d2a
static int xattrs2array(xattrs_type* xattrs, char* **values) {
Packit Service 5e8d2a
    int n = 0;
Packit Service 5e8d2a
    if (xattrs==NULL) { n=1; }
Packit Service 5e8d2a
    else { n=1+xattrs->num; }
Packit Service 5e8d2a
    *values = malloc(n * sizeof(char*));
Packit Service 5e8d2a
    (*values)[0]=malloc((6+floor(log10(n)))*sizeof(char));
Packit Service 5e8d2a
    snprintf((*values)[0], 6+floor(log10(n)), "num=%d", n-1);
Packit Service 5e8d2a
    if (n>1) {
Packit Service 5e8d2a
        size_t num = 0;
Packit Service 5e8d2a
        int width, length;
Packit Service 5e8d2a
        width = log10(xattrs->num); /* make them the same width */
Packit Service 5e8d2a
        while (num++ < xattrs->num) {
Packit Service 5e8d2a
            char *val = NULL;
Packit Service 5e8d2a
            size_t len = 0;
Packit Service 5e8d2a
            val = (char *)xattrs->ents[num - 1].val;
Packit Service 5e8d2a
            len = xstrnspn(val, xattrs->ents[num - 1].vsz, PRINTABLE_XATTR_VALS);
Packit Service 5e8d2a
            if ((len ==  xattrs->ents[num - 1].vsz) || ((len == (xattrs->ents[num - 1].vsz - 1)) && !val[len])) {
Packit Service 5e8d2a
                length = 8 + width + strlen(xattrs->ents[num - 1].key) + strlen(val);
Packit Service 5e8d2a
                (*values)[num]=malloc(length *sizeof(char));
Packit Service 57cbf7
Packit Service 57cbf7
                char * fmt = "[%.*zd] %s = %s";
Packit Service 57cbf7
                if (conf->syslog_format) fmt = "[%.*zd]%s=%s"; // its smaller so it has to be enough space allocated.
Packit Service 57cbf7
                snprintf((*values)[num], length , fmt, width, num, xattrs->ents[num - 1].key, val);
Packit Service 57cbf7
Packit Service 5e8d2a
            } else {
Packit Service 5e8d2a
                val = encode_base64(xattrs->ents[num - 1].val, xattrs->ents[num - 1].vsz);
Packit Service 5e8d2a
                length = 10 + width + strlen(xattrs->ents[num - 1].key) + strlen(val);
Packit Service 5e8d2a
                (*values)[num]=malloc( length  *sizeof(char));
Packit Service 57cbf7
Packit Service 57cbf7
                char * fmt = "[%.*zd] %s <=> %s";
Packit Service 57cbf7
                if (conf->syslog_format) fmt = "[%.*zd]%s<=>%s"; // its smaller so it has to be enough space allocated.
Packit Service 57cbf7
                snprintf((*values)[num], length , fmt, width, num, xattrs->ents[num - 1].key, val);
Packit Service 5e8d2a
                free(val);
Packit Service 5e8d2a
            }
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    return n;
Packit Service 5e8d2a
}
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
Packit Service 5e8d2a
#ifdef WITH_ACL
Packit Service 5e8d2a
static int acl2array(acl_type* acl, char* **values) {
Packit Service 5e8d2a
    int n = 0;
Packit Service 5e8d2a
#ifdef WITH_POSIX_ACL
Packit Service 5e8d2a
#define easy_posix_acl(x,y) \
Packit Service 5e8d2a
        if (acl->x) { \
Packit Service 5e8d2a
            i = k = 0; \
Packit Service 5e8d2a
            while (acl->x[i]) { \
Packit Service 5e8d2a
                if (acl->x[i]=='\n') { \
Packit Service 5e8d2a
                    (*values)[j]=malloc(4+(i-k)*sizeof(char)); \
Packit Service 5e8d2a
                    snprintf((*values)[j], 4+(i-k), "%c: %s", y, &acl->x[k]); \
Packit Service 5e8d2a
                    j++; \
Packit Service 5e8d2a
                    k=i+1; \
Packit Service 5e8d2a
                } \
Packit Service 5e8d2a
                i++; \
Packit Service 5e8d2a
            } \
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    if (acl->acl_a || acl->acl_d) {
Packit Service 5e8d2a
        int j, k, i;
Packit Service 57cbf7
        if (conf->syslog_format) {
Packit Service 57cbf7
            *values = malloc(2 * sizeof(char*));
Packit Service 57cbf7
Packit Service c89282
            char *A= "<NONE>", *D = "<NONE>";
Packit Service 57cbf7
Packit Service 57cbf7
            if (acl->acl_a) { A = acl->acl_a; } 
Packit Service 57cbf7
            if (acl->acl_d) { D = acl->acl_d; } 
Packit Service 57cbf7
Packit Service 57cbf7
            (*values)[0] = (char*) malloc(strlen(A) + 3); // "A:" and \0
Packit Service 57cbf7
            snprintf((*values)[0], strlen(A) + 3, "A:%s", A);
Packit Service 57cbf7
Packit Service 57cbf7
            (*values)[1] = (char*) malloc(strlen(D) + 3); // "D:" and \0
Packit Service 57cbf7
            snprintf((*values)[1], strlen(D) + 3, "D:%s", D);
Packit Service 57cbf7
Packit Service 57cbf7
            i = 0; while ( (*values)[0][i] ) { if ( (*values)[0][i]=='\n') { (*values)[0][i] = ' '; } i++; }
Packit Service 57cbf7
            i = 0; while ( (*values)[1][i] ) { if ( (*values)[1][i]=='\n') { (*values)[1][i] = ' '; } i++; }
Packit Service 57cbf7
Packit Service 57cbf7
            return 2;
Packit Service 57cbf7
        }
Packit Service 57cbf7
Packit Service 5e8d2a
        if (acl->acl_a) { i = 0; while (acl->acl_a[i]) { if (acl->acl_a[i++]=='\n') { n++; } } }
Packit Service 5e8d2a
        if (acl->acl_d) { i = 0; while (acl->acl_d[i]) { if (acl->acl_d[i++]=='\n') { n++; } } }
Packit Service 5e8d2a
        *values = malloc(n * sizeof(char*));
Packit Service 5e8d2a
        j = 0;
Packit Service 5e8d2a
        easy_posix_acl(acl_a, 'A')
Packit Service 5e8d2a
        easy_posix_acl(acl_d, 'D')
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_SUN_ACL
Packit Service 5e8d2a
/* FIXME: readd sun acl support */
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
    return n;
Packit Service 5e8d2a
}
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
Packit Service 5e8d2a
#ifdef WITH_E2FSATTRS
Packit Service 5e8d2a
static char* e2fsattrs2string(unsigned long flags, int flags_only) {
Packit Service 5e8d2a
    int length = sizeof(flag_bits)/sizeof(long);
Packit Service 5e8d2a
    char* string = malloc ((length+1) * sizeof (char));
Packit Service 5e8d2a
    int j = 0;
Packit Service 5e8d2a
    for (int i = 0 ; i < length ; i++) {
Packit Service 5e8d2a
        if (!flags_only && flag_bits[i]&(conf->report_ignore_e2fsattrs)) {
Packit Service 5e8d2a
            string[j++]=':';
Packit Service 5e8d2a
        } else if (flag_bits[i] & flags) {
Packit Service 5e8d2a
            string[j++]=flag_char[i];
Packit Service 5e8d2a
        } else if (!flags_only) {
Packit Service 5e8d2a
            string[j++]='-';
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    string[j] = '\0';
Packit Service 5e8d2a
    return string;
Packit Service 5e8d2a
}
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
Packit Service 5e8d2a
static char* get_file_type_string(mode_t mode) {
Packit Service 5e8d2a
    switch (mode & S_IFMT) {
Packit Service 57cbf7
        case S_IFREG: return conf->syslog_format ? "file" : _("File");
Packit Service 57cbf7
        case S_IFDIR: return conf->syslog_format ? "dir" : _("Directory");
Packit Service 5e8d2a
#ifdef S_IFIFO
Packit Service 57cbf7
        case S_IFIFO: return conf->syslog_format ? "fifo" : _("FIFO");
Packit Service 5e8d2a
#endif
Packit Service 57cbf7
        case S_IFLNK: return conf->syslog_format ? "link" : _("Link");
Packit Service 57cbf7
        case S_IFBLK: return conf->syslog_format ? "blockd" : _("Block device");
Packit Service 57cbf7
        case S_IFCHR: return conf->syslog_format ? "chard" : _("Character device");
Packit Service 5e8d2a
#ifdef S_IFSOCK
Packit Service 57cbf7
        case S_IFSOCK: return conf->syslog_format ? "socket" : _("Socket");
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef S_IFDOOR
Packit Service 57cbf7
        case S_IFDOOR: return conf->syslog_format ? "door" : _("Door");
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef S_IFPORT
Packit Service 57cbf7
        case S_IFPORT: return conf->syslog_format ? "port" : _("Port");
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
        case 0: return NULL;
Packit Service 57cbf7
        default: return conf->syslog_format ? "unknown" : _("Unknown file type");
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static char* byte_to_base16(byte* src, size_t ssize) {
Packit Service 5e8d2a
    char* str = malloc((2*ssize+1) * sizeof (char));
Packit Service 5e8d2a
    size_t i;
Packit Service 5e8d2a
    for(i=0; i < ssize; ++i) {
Packit Service 5e8d2a
        snprintf(&str[2*i], 3, "%02x", src[i]);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    return str;
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static int get_attribute_values(DB_ATTR_TYPE attr, db_line* line,
Packit Service 5e8d2a
        char* **values) {
Packit Service 5e8d2a
Packit Service 5e8d2a
#define easy_string(s) \
Packit Service 5e8d2a
l = strlen(s)+1; \
Packit Service 5e8d2a
*values[0] = malloc(l * sizeof (char)); \
Packit Service 5e8d2a
snprintf(*values[0], l, "%s",s);
Packit Service 5e8d2a
Packit Service 5e8d2a
#define easy_md(a,b,c) \
Packit Service 5e8d2a
} else if (a&attr) { \
Packit Service 5e8d2a
    if (conf->report_base16) { \
Packit Service 5e8d2a
        *values[0] = byte_to_base16(line->b, c); \
Packit Service 5e8d2a
    } else { \
Packit Service 5e8d2a
        *values[0] = encode_base64(line->b, c); \
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
Packit Service 5e8d2a
#define easy_number(a,b,c) \
Packit Service 5e8d2a
} else if (a&attr) { \
Packit Service 5e8d2a
    l = 2+floor(line->b?log10(line->b):0); \
Packit Service 5e8d2a
    *values[0] = malloc(l * sizeof (char)); \
Packit Service 5e8d2a
    snprintf(*values[0], l, c,line->b);
Packit Service 5e8d2a
Packit Service 5e8d2a
#define easy_time(a,b) \
Packit Service 5e8d2a
} else if (a&attr) { \
Packit Service 5e8d2a
    *values[0] = malloc(time_string_len * sizeof (char));  \
Packit Service 5e8d2a
    strftime(*values[0], time_string_len, time_format, localtime(&(line->b)));
Packit Service 5e8d2a
Packit Service 5e8d2a
    int l;
Packit Service 5e8d2a
    if (line==NULL || !(line->attr&attr)) {
Packit Service 5e8d2a
        *values = NULL;
Packit Service 5e8d2a
        return 0;
Packit Service 5e8d2a
#ifdef WITH_ACL
Packit Service 5e8d2a
    } else if (DB_ACL&attr) {
Packit Service 5e8d2a
        return acl2array(line->acl, &*values);
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_XATTR
Packit Service 5e8d2a
    } else if (DB_XATTRS&attr) {
Packit Service 5e8d2a
        return xattrs2array(line->xattrs, &*values);
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
    } else {
Packit Service 5e8d2a
        *values = malloc(1 * sizeof (char*));
Packit Service 5e8d2a
        if (DB_FTYPE&attr) {
Packit Service 5e8d2a
            easy_string(get_file_type_string(line->perm))
Packit Service 5e8d2a
        } else if (DB_LINKNAME&attr) {
Packit Service 5e8d2a
            easy_string(line->linkname)
Packit Service 5e8d2a
        easy_number((DB_SIZE|DB_SIZEG),size,"%li")
Packit Service 5e8d2a
        } else if (DB_PERM&attr) {
Packit Service 5e8d2a
            *values[0] = perm_to_char(line->perm);
Packit Service 5e8d2a
        easy_time(DB_ATIME,atime)
Packit Service 5e8d2a
        easy_time(DB_MTIME,mtime)
Packit Service 5e8d2a
        easy_time(DB_CTIME,ctime)
Packit Service 5e8d2a
        easy_number(DB_BCOUNT,bcount,"%li")
Packit Service 5e8d2a
        easy_number(DB_UID,uid,"%i")
Packit Service 5e8d2a
        easy_number(DB_GID,gid,"%i")
Packit Service 5e8d2a
        easy_number(DB_INODE,inode,"%lu")
Packit Service 5e8d2a
        easy_number(DB_LNKCOUNT,nlink,"%lu")
Packit Service 5e8d2a
        easy_md(DB_MD5,md5,HASH_MD5_LEN)
Packit Service 5e8d2a
        easy_md(DB_SHA1,sha1,HASH_SHA1_LEN)
Packit Service 5e8d2a
        easy_md(DB_RMD160,rmd160,HASH_RMD160_LEN)
Packit Service 5e8d2a
        easy_md(DB_TIGER,tiger,HASH_TIGER_LEN)
Packit Service 5e8d2a
        easy_md(DB_SHA256,sha256,HASH_SHA256_LEN)
Packit Service 5e8d2a
        easy_md(DB_SHA512,sha512,HASH_SHA512_LEN)
Packit Service 5e8d2a
#ifdef WITH_MHASH
Packit Service 5e8d2a
        easy_md(DB_CRC32,crc32,HASH_CRC32_LEN)
Packit Service 5e8d2a
        easy_md(DB_HAVAL,haval,HASH_HAVAL256_LEN)
Packit Service 5e8d2a
        easy_md(DB_GOST,gost,HASH_GOST_LEN)
Packit Service 5e8d2a
        easy_md(DB_CRC32B,crc32b,HASH_CRC32B_LEN)
Packit Service 5e8d2a
        easy_md(DB_WHIRLPOOL,whirlpool,HASH_WHIRLPOOL_LEN)
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_SELINUX
Packit Service 5e8d2a
        } else if (DB_SELINUX&attr) {
Packit Service 5e8d2a
            easy_string(line->cntx)
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
#ifdef WITH_E2FSATTRS
Packit Service 5e8d2a
        } else if (DB_E2FSATTRS&attr) {
Packit Service 5e8d2a
            *values[0]=e2fsattrs2string(line->e2fsattrs, 0);
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
        } else {
Packit Service 5e8d2a
            easy_string("unknown attribute")
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
        return 1;
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static void print_line(seltree* node) {
Packit Service 5e8d2a
    if(conf->summarize_changes==1) {
Packit Service 5e8d2a
        int i;
Packit Service 5e8d2a
        int length = sizeof(summary_attributes)/sizeof(DB_ATTR_TYPE);
Packit Service 5e8d2a
        char* summary = malloc ((length+1) * sizeof (char));
Packit Service 5e8d2a
        if (node->checked&(NODE_ADDED|NODE_REMOVED)) {
Packit Service 5e8d2a
            summary[0]=get_file_type_char((node->checked&NODE_REMOVED?node->old_data:node->new_data)->perm);
Packit Service 5e8d2a
            for(i=1;i
Packit Service 5e8d2a
                summary[i]=node->checked&NODE_ADDED?'+':'-';
Packit Service 5e8d2a
            }
Packit Service 5e8d2a
        } else if (node->checked&NODE_CHANGED) {
Packit Service 5e8d2a
            char c, u, a, r, g, s;
Packit Service 5e8d2a
            for(i=0;i
Packit Service 5e8d2a
                c = summary_char[i];
Packit Service 5e8d2a
                r = '-'; a = '+'; g = ':'; u = '.'; s = ' ';
Packit Service 5e8d2a
                switch (i) {
Packit Service 5e8d2a
                    case 0:
Packit Service 5e8d2a
                        summary[i]=get_file_type_char((node->new_data)->perm);
Packit Service 5e8d2a
                        continue;
Packit Service 5e8d2a
                    case 2:
Packit Service 5e8d2a
                        if (summary_attributes[i]&(node->changed_attrs&(~ignored_changed_attrs)) && (node->old_data)->size > (node->new_data)->size) {
Packit Service 5e8d2a
                            c = '<';
Packit Service 5e8d2a
                        }
Packit Service 5e8d2a
                        u = '=';
Packit Service 5e8d2a
                        break;
Packit Service 5e8d2a
                }
Packit Service 5e8d2a
                if (summary_attributes[i]&node->changed_attrs&(forced_attrs|(~ignored_changed_attrs))) {
Packit Service 5e8d2a
                    summary[i]=c;
Packit Service 5e8d2a
                } else if (summary_attributes[i]&((node->old_data)->attr&~((node->new_data)->attr)&(forced_attrs|~(ignored_removed_attrs)))) {
Packit Service 5e8d2a
                    summary[i]=r;
Packit Service 5e8d2a
                } else if (summary_attributes[i]&~((node->old_data)->attr)&(node->new_data)->attr&(forced_attrs|~(ignored_added_attrs))) {
Packit Service 5e8d2a
                    summary[i]=a;
Packit Service 5e8d2a
                } else if (summary_attributes[i]& (
Packit Service 5e8d2a
                             (((node->old_data)->attr&~((node->new_data)->attr)&ignored_removed_attrs))|
Packit Service 5e8d2a
                            (~((node->old_data)->attr)&(node->new_data)->attr&ignored_added_attrs)|
Packit Service 5e8d2a
                             (((node->old_data)->attr&(node->new_data)->attr)&ignored_changed_attrs)
Packit Service 5e8d2a
                            ) ) {
Packit Service 5e8d2a
                    summary[i]=g;
Packit Service 5e8d2a
                } else if (summary_attributes[i]&((node->old_data)->attr&(node->new_data)->attr)) {
Packit Service 5e8d2a
                    summary[i]=u;
Packit Service 5e8d2a
                } else {
Packit Service 5e8d2a
                    summary[i]=s;
Packit Service 5e8d2a
                }
Packit Service 5e8d2a
            }
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
        summary[length]='\0';
Packit Service 5e8d2a
        error(2,"\n%s: %s", summary, (node->checked&NODE_REMOVED?node->old_data:node->new_data)->filename);
Packit Service 5e8d2a
        free(summary); summary=NULL;
Packit Service 5e8d2a
    } else {
Packit Service 5e8d2a
        if (node->checked&NODE_ADDED) {
Packit Service 5e8d2a
            error(2,"added: %s\n",(node->new_data)->filename);
Packit Service 5e8d2a
        } else if (node->checked&NODE_REMOVED) {
Packit Service 5e8d2a
            error(2,"removed: %s\n",(node->old_data)->filename);
Packit Service 5e8d2a
        } else if (node->checked&NODE_CHANGED) {
Packit Service 5e8d2a
            error(2,"changed: %s\n",(node->new_data)->filename);
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static void print_dbline_attributes(db_line* oline, db_line* nline, DB_ATTR_TYPE
Packit Service 5e8d2a
        changed_attrs, DB_ATTR_TYPE force_attrs) {
Packit Service 5e8d2a
    char **ovalue, **nvalue;
Packit Service 5e8d2a
    int onumber, nnumber, olen, nlen, i, j, k, c;
Packit Service 5e8d2a
    int length = sizeof(details_attributes)/sizeof(DB_ATTR_TYPE);
Packit Service 5e8d2a
    int p = (width_details-(width_details%2?13:14))/2;
Packit Service 5e8d2a
    DB_ATTR_TYPE attrs;
Packit Service 5e8d2a
    error(2,"\n");
Packit Service 5e8d2a
    char *file_type = get_file_type_string((nline==NULL?oline:nline)->perm);
Packit Service 5e8d2a
    if (file_type) {
Packit Service 5e8d2a
        error(2,"%s: ", file_type);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    error(2,"%s\n", (nline==NULL?oline:nline)->filename);
Packit Service 5e8d2a
    attrs=force_attrs|(~(ignored_changed_attrs)&changed_attrs);
Packit Service 5e8d2a
    for (j=0; j < length; ++j) {
Packit Service 5e8d2a
        if (details_attributes[j]&attrs) {
Packit Service 5e8d2a
            onumber=get_attribute_values(details_attributes[j], oline, &ovalue);
Packit Service 5e8d2a
            nnumber=get_attribute_values(details_attributes[j], nline, &nvalue);
Packit Service 5e8d2a
            i = 0;
Packit Service 5e8d2a
            while (i
Packit Service 5e8d2a
                olen = i
Packit Service 5e8d2a
                nlen = i
Packit Service 5e8d2a
                k = 0;
Packit Service 5e8d2a
                while (olen-p*k >= 0 || nlen-p*k >= 0) {
Packit Service 5e8d2a
                    c = k*(p-1);
Packit Service 5e8d2a
                    if (!onumber) {
Packit Service 5e8d2a
                        error(2," %s%-9s%c %-*c  %.*s\n", width_details%2?"":" ", i+k?"":details_string[j], i+k?' ':':', p, ' ', p-1, nlen-c>0?&nvalue[i][c]:"");
Packit Service 5e8d2a
                    } else if (!nnumber) {
Packit Service 5e8d2a
                        error(2," %s%-9s%c %.*s\n", width_details%2?"":" ", i+k?"":details_string[j], i+k?' ':':', p-1, olen-c>0?&ovalue[i][c]:"");
Packit Service 5e8d2a
                    } else {
Packit Service 5e8d2a
                        error(2," %s%-9s%c %-*.*s| %.*s\n", width_details%2?"":" ", i+k?"":details_string[j], i+k?' ':':', p, p-1, olen-c>0?&ovalue[i][c]:"", p-1, nlen-c>0?&nvalue[i][c]:"");
Packit Service 5e8d2a
                    }
Packit Service 5e8d2a
                    k++;
Packit Service 5e8d2a
                }
Packit Service 5e8d2a
                ++i;
Packit Service 5e8d2a
            }
Packit Service 5e8d2a
            for(i=0; i < onumber; ++i) { free(ovalue[i]); ovalue[i]=NULL; } free(ovalue); ovalue=NULL;
Packit Service 5e8d2a
            for(i=0; i < nnumber; ++i) { free(nvalue[i]); nvalue[i]=NULL; } free(nvalue); nvalue=NULL;
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 57cbf7
Packit Service 57cbf7
static void print_dbline_attributes_syslog(db_line* oline, db_line* nline, DB_ATTR_TYPE
Packit Service 57cbf7
        changed_attrs, DB_ATTR_TYPE force_attrs) {
Packit Service 57cbf7
    char **ovalue, **nvalue;
Packit Service 57cbf7
    int onumber, nnumber, i, j;
Packit Service 57cbf7
    int length = sizeof(details_attributes)/sizeof(DB_ATTR_TYPE);
Packit Service 57cbf7
    DB_ATTR_TYPE attrs;
Packit Service 57cbf7
    char *file_type = get_file_type_string((nline==NULL?oline:nline)->perm);
Packit Service 57cbf7
    if (file_type) {
Packit Service 57cbf7
        error(0,"%s=", file_type);
Packit Service 57cbf7
    }
Packit Service 57cbf7
    error(0,"%s", (nline==NULL?oline:nline)->filename);
Packit Service 57cbf7
    attrs=force_attrs|(~(ignored_changed_attrs)&changed_attrs);
Packit Service 57cbf7
    for (j=0; j < length; ++j) {
Packit Service 57cbf7
        if (details_attributes[j]&attrs) {
Packit Service 57cbf7
            onumber=get_attribute_values(details_attributes[j], oline, &ovalue);
Packit Service 57cbf7
            nnumber=get_attribute_values(details_attributes[j], nline, &nvalue);
Packit Service 57cbf7
Packit Service 57cbf7
            if (details_attributes[j] == DB_ACL || details_attributes[j] == DB_XATTRS) {
Packit Service 57cbf7
Packit Service 57cbf7
                error(0, ";%s_old=|", details_string[j]);
Packit Service 57cbf7
Packit Service 57cbf7
                for (i = 0 ; i < onumber ; i++) {
Packit Service 57cbf7
                    error(0, "%s|", ovalue[i]);
Packit Service 57cbf7
                }
Packit Service 57cbf7
Packit Service 57cbf7
                error(0, ";%s_new=|", details_string[j]);
Packit Service 57cbf7
Packit Service 57cbf7
                for (i = 0 ; i < nnumber ; i++) {
Packit Service 57cbf7
                    error(0, "%s|", nvalue[i]);
Packit Service 57cbf7
                }
Packit Service 57cbf7
Packit Service 57cbf7
            } else {
Packit Service 57cbf7
Packit Service 57cbf7
                error(0, ";%s_old=%s;%s_new=%s", details_string[j], *ovalue, details_string[j], *nvalue);
Packit Service 57cbf7
Packit Service 57cbf7
            }
Packit Service 57cbf7
Packit Service 57cbf7
            for(i=0; i < onumber; ++i) { free(ovalue[i]); ovalue[i]=NULL; } free(ovalue); ovalue=NULL;
Packit Service 57cbf7
            for(i=0; i < nnumber; ++i) { free(nvalue[i]); nvalue[i]=NULL; } free(nvalue); nvalue=NULL;
Packit Service 57cbf7
        }
Packit Service 57cbf7
    }
Packit Service 57cbf7
    error(0, "\n");
Packit Service 57cbf7
}
Packit Service 57cbf7
Packit Service 5e8d2a
static void print_attributes_added_node(db_line* line) {
Packit Service 5e8d2a
    print_dbline_attributes(NULL, line, 0, line->attr);
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static void print_attributes_removed_node(db_line* line) {
Packit Service 5e8d2a
    print_dbline_attributes(line, NULL, 0, line->attr);
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 57cbf7
static void print_attributes_added_node_syslog(db_line* line) {
Packit Service 57cbf7
Packit Service 57cbf7
    char *file_type = get_file_type_string(line->perm);
Packit Service 57cbf7
    if (file_type) {
Packit Service 57cbf7
        error(0,"%s=", file_type);
Packit Service 57cbf7
    }
Packit Service 57cbf7
    error(0,"%s; added\n", line->filename);
Packit Service 57cbf7
Packit Service 57cbf7
}
Packit Service 57cbf7
Packit Service 57cbf7
static void print_attributes_removed_node_syslog(db_line* line) {
Packit Service 57cbf7
Packit Service 57cbf7
    char *file_type = get_file_type_string(line->perm);
Packit Service 57cbf7
    if (file_type) {
Packit Service 57cbf7
        error(0,"%s=", file_type);
Packit Service 57cbf7
    }
Packit Service 57cbf7
    error(0,"%s; removed\n", line->filename);
Packit Service 57cbf7
Packit Service 57cbf7
}
Packit Service 57cbf7
Packit Service 5e8d2a
static void terse_report(seltree* node) {
Packit Service 5e8d2a
    list* r=NULL;
Packit Service 5e8d2a
    if ((node->checked&(DB_OLD|DB_NEW)) != 0) {
Packit Service 5e8d2a
        ntotal += ((node->checked&DB_NEW) != 0);
Packit Service 5e8d2a
        if (!(node->checked&DB_OLD)){
Packit Service 5e8d2a
            /* File is in new db but not old. (ADDED) */
Packit Service 5e8d2a
            /* unless it was moved in */
Packit Service 5e8d2a
            if (!((node->checked&NODE_ALLOW_NEW)||(node->checked&NODE_MOVED_IN))) {
Packit Service 5e8d2a
                nadd++;
Packit Service 5e8d2a
                node->checked|=NODE_ADDED;
Packit Service 5e8d2a
            }
Packit Service 5e8d2a
        } else if (!(node->checked&DB_NEW)){
Packit Service 5e8d2a
            /* File is in old db but not new. (REMOVED) */
Packit Service 5e8d2a
            /* unless it was moved out */
Packit Service 5e8d2a
            if (!((node->checked&NODE_ALLOW_RM)||(node->checked&NODE_MOVED_OUT))) {
Packit Service 5e8d2a
                nrem++;
Packit Service 5e8d2a
                node->checked|=NODE_REMOVED;
Packit Service 5e8d2a
            }
Packit Service 5e8d2a
        } else if ((node->old_data!=NULL)&&(node->new_data!=NULL)){
Packit Service 5e8d2a
            /* File is in both db's and the data is still there. (CHANGED) */
Packit Service 5e8d2a
            if (!(node->checked&(NODE_MOVED_IN|NODE_MOVED_OUT))){
Packit Service 5e8d2a
                nchg++;
Packit Service 5e8d2a
                node->checked|=NODE_CHANGED;
Packit Service 5e8d2a
            }else if (!((node->checked&NODE_ALLOW_NEW)||(node->checked&NODE_MOVED_IN))) {
Packit Service 5e8d2a
                nadd++;
Packit Service 5e8d2a
                node->checked|=NODE_ADDED;
Packit Service 5e8d2a
            }else if (!((node->checked&NODE_ALLOW_RM)||(node->checked&NODE_MOVED_OUT))) {
Packit Service 5e8d2a
                nrem++;
Packit Service 5e8d2a
                node->checked|=NODE_REMOVED;
Packit Service 5e8d2a
            }
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    for (r=node->childs;r;r=r->next) {
Packit Service 5e8d2a
        terse_report((seltree*)r->data);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static void print_report_list(seltree* node, const int node_status) {
Packit Service 5e8d2a
    list* r=NULL;
Packit Service 5e8d2a
    if (node->checked&node_status) {
Packit Service 5e8d2a
        print_line(node);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    for(r=node->childs;r;r=r->next){
Packit Service 5e8d2a
        print_report_list((seltree*)r->data, node_status);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static void print_report_details(seltree* node) {
Packit Service 5e8d2a
    list* r=NULL;
Packit Service 5e8d2a
    if (conf->verbose_level>=5) {
Packit Service 5e8d2a
        if (node->checked&NODE_CHANGED) {
Packit Service 5e8d2a
            print_dbline_attributes(node->old_data, node->new_data, node->changed_attrs, (conf->verbose_level>=6?(
Packit Service 5e8d2a
                ((node->old_data)->attr&~((node->new_data)->attr)&~(ignored_removed_attrs))|(~((node->old_data)->attr)&(node->new_data)->attr&~(ignored_added_attrs))
Packit Service 5e8d2a
                            ):0)|forced_attrs);
Packit Service 5e8d2a
        } else if ((conf->verbose_level>=7)) {
Packit Service 5e8d2a
            if (node->checked&NODE_ADDED) { print_attributes_added_node(node->new_data); }
Packit Service 5e8d2a
            if (node->checked&NODE_REMOVED) { print_attributes_removed_node(node->old_data); }
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    for(r=node->childs;r;r=r->next){
Packit Service 5e8d2a
        print_report_details((seltree*)r->data);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 57cbf7
static void print_syslog_format(seltree* node) {
Packit Service 57cbf7
    list* r=NULL;
Packit Service 57cbf7
Packit Service 57cbf7
    if (node->checked&NODE_CHANGED) {
Packit Service 57cbf7
        print_dbline_attributes_syslog(node->old_data, node->new_data, node->changed_attrs, forced_attrs);
Packit Service 57cbf7
    }
Packit Service 57cbf7
   
Packit Service 57cbf7
    if (node->checked&NODE_ADDED) {
Packit Service 57cbf7
        print_attributes_added_node_syslog(node->new_data);
Packit Service 57cbf7
    }
Packit Service 57cbf7
Packit Service 57cbf7
    if (node->checked&NODE_REMOVED) {
Packit Service 57cbf7
        print_attributes_removed_node_syslog(node->old_data); 
Packit Service 57cbf7
    }
Packit Service 57cbf7
        
Packit Service 57cbf7
    for(r=node->childs;r;r=r->next){
Packit Service 57cbf7
        print_syslog_format((seltree*)r->data);
Packit Service 57cbf7
    }
Packit Service 57cbf7
}
Packit Service 57cbf7
Packit Service 5e8d2a
static void print_report_header() {
Packit Service 5e8d2a
    char *time;
Packit Service 5e8d2a
    int first = 1;
Packit Service 5e8d2a
Packit Service 5e8d2a
    time = malloc(time_string_len * sizeof (char));
Packit Service 5e8d2a
    strftime(time, time_string_len, time_format, localtime(&(conf->start_time)));
Packit Service 5e8d2a
    error(2,_("Start timestamp: %s (AIDE " AIDEVERSION ")\n"), time);
Packit Service 5e8d2a
    free(time); time=NULL;
Packit Service 5e8d2a
Packit Service 5e8d2a
    error(0,_("AIDE"));
Packit Service 5e8d2a
    if(conf->action&(DO_COMPARE|DO_DIFF)) {
Packit Service 5e8d2a
        error(0,_(" found %sdifferences between %s%s!!\n"), (nadd||nrem||nchg)?"":"NO ", conf->action&DO_COMPARE?_("database and filesystem"):_("the two databases"), (nadd||nrem||nchg)?"":_(". Looks okay"));
Packit Service 5e8d2a
        if(conf->action&(DO_INIT)) {
Packit Service 5e8d2a
            error(0,_("New AIDE database written to %s\n"),conf->db_out_url->value);
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    } else {
Packit Service 5e8d2a
        error(0,_(" initialized database at %s\n"),conf->db_out_url->value);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
Packit Service 5e8d2a
    if(conf->config_version)
Packit Service 5e8d2a
        error(2,_("Config version used: %s\n"),conf->config_version);
Packit Service 5e8d2a
Packit Service 5e8d2a
    if (conf->limit != NULL) {
Packit Service 5e8d2a
        error (2,_("Limit: %s"), conf->limit);
Packit Service 5e8d2a
        first = 0;
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    if (conf->action&(DO_INIT|DO_COMPARE) && conf->root_prefix_length > 0) {
Packit Service 5e8d2a
        if (first) { first=0; }
Packit Service 5e8d2a
        else { error (2," | "); }
Packit Service 5e8d2a
        error (2,_("Root prefix: %s"),conf->root_prefix);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    if (conf->verbose_level != 5) {
Packit Service 5e8d2a
        if (first) { first=0; }
Packit Service 5e8d2a
        else { error (2," | "); }
Packit Service 5e8d2a
        error (2,_("Verbose level: %d"), conf->verbose_level);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    if (!first) { error (2,"\n"); }
Packit Service 5e8d2a
    if (ignored_added_attrs) {
Packit Service 5e8d2a
        error (2,_("Ignored added attributes: %s\n"),report_attrs(ignored_added_attrs));
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    if (ignored_removed_attrs) {
Packit Service 5e8d2a
        error (2,_("Ignored removed attributes: %s\n"),report_attrs(ignored_removed_attrs));
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    if (ignored_changed_attrs) {
Packit Service 5e8d2a
        error (2,_("Ignored changed attributes: %s\n"),report_attrs(ignored_changed_attrs));
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
    if (forced_attrs) {
Packit Service 5e8d2a
        error (2,_("Forced attributes: %s\n"),report_attrs(forced_attrs));
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
#ifdef WITH_E2FSATTRS
Packit Service 5e8d2a
    if (conf->report_ignore_e2fsattrs) {
Packit Service 5e8d2a
        error (2,_("Ignored e2fs attributes: %s\n"), e2fsattrs2string(conf->report_ignore_e2fsattrs, 1) );
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
Packit Service 5e8d2a
    if(conf->action&(DO_COMPARE|DO_DIFF) && (nadd||nrem||nchg)) {
Packit Service 5e8d2a
        error(0,_("\nSummary:\n  Total number of entries:\t%li\n  Added entries:\t\t%li\n"
Packit Service 5e8d2a
                    "  Removed entries:\t\t%li\n  Changed entries:\t\t%li"), ntotal, nadd, nrem, nchg);
Packit Service 5e8d2a
    } else {
Packit Service 5e8d2a
        error(0,_("\nNumber of entries:\t%li"), ntotal);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static void print_report_databases() {
Packit Service 5e8d2a
    if (conf->verbose_level>=2 && (conf->line_db_in || conf->line_db_out)) {
Packit Service 5e8d2a
        error(2,(char*)report_top_format,_("The attributes of the (uncompressed) database(s)"));
Packit Service 5e8d2a
        if (conf->line_db_in) {
Packit Service 5e8d2a
            print_attributes_removed_node(conf->line_db_in);
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
        if (conf->line_db_out) {
Packit Service 5e8d2a
            print_attributes_removed_node(conf->line_db_out);
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
static void print_report_footer()
Packit Service 5e8d2a
{
Packit Service 5e8d2a
  char *time = malloc(time_string_len * sizeof (char));
Packit Service 5e8d2a
  int run_time = (int) difftime(conf->end_time, conf->start_time);
Packit Service 5e8d2a
Packit Service 5e8d2a
  strftime(time, time_string_len, time_format, localtime(&(conf->end_time)));
Packit Service 5e8d2a
  error(2,_("\n\nEnd timestamp: %s (run time: %dm %ds)\n"), time, run_time/60, run_time%60);
Packit Service 5e8d2a
  free(time); time=NULL;
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
#ifdef WITH_AUDIT
Packit Service 5e8d2a
  /* Something changed, send audit anomaly message */
Packit Service 5e8d2a
void send_audit_report()
Packit Service 5e8d2a
{
Packit Service 5e8d2a
  if(nadd!=0||nrem!=0||nchg!=0){
Packit Service 5e8d2a
    int fd=audit_open();
Packit Service 5e8d2a
    if (fd>=0){
Packit Service 5e8d2a
       char msg[64];
Packit Service 5e8d2a
Packit Service 5e8d2a
       snprintf(msg, sizeof(msg), "added=%ld removed=%ld changed=%ld", 
Packit Service 5e8d2a
                nadd, nrem, nchg);
Packit Service 5e8d2a
Packit Service 5e8d2a
       if (audit_log_user_message(fd, AUDIT_ANOM_RBAC_INTEGRITY_FAIL,
Packit Service 5e8d2a
                                  msg, NULL, NULL, NULL, 0)<=0)
Packit Service 5e8d2a
#ifdef HAVE_SYSLOG
Packit Service 5e8d2a
          syslog(LOG_ERR, "Failed sending audit message:%s", msg);
Packit Service 5e8d2a
#else
Packit Service 5e8d2a
          ;
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
       close(fd);
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
  }
Packit Service 5e8d2a
}
Packit Service 5e8d2a
#endif /* WITH_AUDIT */
Packit Service 5e8d2a
Packit Service 5e8d2a
int gen_report(seltree* node) {
Packit Service 5e8d2a
    forced_attrs = get_special_report_group("report_force_attrs");
Packit Service 5e8d2a
    ignored_added_attrs = get_special_report_group("report_ignore_added_attrs");
Packit Service 5e8d2a
    ignored_removed_attrs = get_special_report_group("report_ignore_removed_attrs");
Packit Service 5e8d2a
    ignored_changed_attrs = get_special_report_group("report_ignore_changed_attrs");
Packit Service 5e8d2a
Packit Service 5e8d2a
    terse_report(node);
Packit Service 5e8d2a
#ifdef WITH_AUDIT
Packit Service 5e8d2a
    send_audit_report();
Packit Service 5e8d2a
#endif
Packit Service 5e8d2a
    if ((nadd|nrem|nchg) > 0 || conf->report_quiet == 0) {
Packit Service 57cbf7
Packit Service 57cbf7
        if (!conf->syslog_format) {
Packit Service 57cbf7
            print_report_header();
Packit Service 5e8d2a
        }
Packit Service 57cbf7
Packit Service 57cbf7
        if(conf->action&(DO_COMPARE|DO_DIFF) || (conf->action&DO_INIT && conf->report_detailed_init) ) {
Packit Service 57cbf7
            if (!conf->syslog_format && conf->grouped) {
Packit Service 57cbf7
                if (nadd) {
Packit Service 57cbf7
                    error(2,(char*)report_top_format,_("Added entries"));
Packit Service 57cbf7
                    print_report_list(node, NODE_ADDED);
Packit Service 57cbf7
                }
Packit Service 57cbf7
                if (nrem) {
Packit Service 57cbf7
                    error(2,(char*)report_top_format,_("Removed entries"));
Packit Service 57cbf7
                    print_report_list(node, NODE_REMOVED);
Packit Service 57cbf7
                }
Packit Service 57cbf7
                if (nchg) {
Packit Service 57cbf7
                    error(2,(char*)report_top_format,_("Changed entries"));
Packit Service 57cbf7
                    print_report_list(node, NODE_CHANGED);
Packit Service 57cbf7
                }
Packit Service 57cbf7
            } else if (!conf->syslog_format && ( nadd || nrem || nchg ) ) {
Packit Service 57cbf7
                if (nadd && nrem && nchg) { error(2,(char*)report_top_format,_("Added, removed and changed entries")); }
Packit Service 57cbf7
                else if (nadd && nrem) { error(2,(char*)report_top_format,_("Added and removed entries")); }
Packit Service 57cbf7
                else if (nadd && nchg) { error(2,(char*)report_top_format,_("Added and changed entries")); }
Packit Service 57cbf7
                else if (nrem && nchg) { error(2,(char*)report_top_format,_("Removed and changed entries")); }
Packit Service 57cbf7
                else if (nadd) { error(2,(char*)report_top_format,_("Added entries")); }
Packit Service 57cbf7
                else if (nrem) { error(2,(char*)report_top_format,_("Removed entries")); }
Packit Service 57cbf7
                else if (nchg) { error(2,(char*)report_top_format,_("Changed entries")); }
Packit Service 57cbf7
                print_report_list(node, NODE_ADDED|NODE_REMOVED|NODE_CHANGED);
Packit Service 57cbf7
            }
Packit Service 57cbf7
            if (nadd || nrem || nchg) {
Packit Service 57cbf7
                if (!conf->syslog_format) {
Packit Service 57cbf7
                    error(nchg?5:7,(char*)report_top_format,_("Detailed information about changes"));
Packit Service 57cbf7
                    print_report_details(node);
Packit Service 57cbf7
                } else {
Packit Service 57cbf7
                    /* Syslog Format */
Packit Service 57cbf7
                    error(0, "AIDE found differences between database and filesystem!!\n");
Packit Service 57cbf7
                    error(0, "summary;total_number_of_files=%ld;added_files=%ld;"
Packit Service 57cbf7
                              "removed_files=%ld;changed_files=%ld\n",ntotal,nadd,nrem,nchg);
Packit Service 57cbf7
                    print_syslog_format(node);
Packit Service 57cbf7
                }
Packit Service 57cbf7
            }
Packit Service 5e8d2a
        }
Packit Service 57cbf7
        if (!conf->syslog_format) {
Packit Service 57cbf7
            print_report_databases();
Packit Service 57cbf7
            conf->end_time=time(&(conf->end_time));
Packit Service 57cbf7
            print_report_footer();
Packit Service 5e8d2a
        }
Packit Service 5e8d2a
    }
Packit Service 5e8d2a
Packit Service 5e8d2a
    return conf->action&(DO_COMPARE|DO_DIFF) ? (nadd!=0)*1+(nrem!=0)*2+(nchg!=0)*4 : 0;
Packit Service 5e8d2a
}
Packit Service 5e8d2a
Packit Service 5e8d2a
const char* aide_key_9=CONFHMACKEY_09;
Packit Service 5e8d2a
const char* db_key_9=DBHMACKEY_09;
Packit Service 5e8d2a
Packit Service 5e8d2a
// vi: ts=8 sw=8