audit_tool.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,802 行 · 第 1/5 页

C
1,802
字号
    extern char *trustedevent[];    int match = 0;    char *eventp;    char *hostp;    int i, j, k;    /* search for a rule which matches current audit record */    for ( i = 0; i < ruleno; i++ ) {        /* compare hostname against rules */        if ( RULE(i,host)[0] == '*' ) match = 1;        else {            hostp = gethost_l(af->ipaddr);            for ( j = 0; RULE(i,host)[j] == hostp[j] && hostp[j]; j++ );            if ( RULE(i,host)[j] == '\0' && hostp[j] == '\0' ) match = 1;        }        /* compare auid, ruid against rules */        if ( match )            match = ((af->auid == RULE(i,auid)) || (RULE(i,auid) == -1));        if ( match )            match = ((af->ruid == RULE(i,ruid)) || (RULE(i,ruid) == -1));        /* compare event against rules */        if ( match ) {            match = 0;            if ( af->event == SYS_exit && af->login_proc )                eventp = _LOGOUT;            else if ( af->event >= 0 && af->event <= NUM_SYSCALLS )                 eventp = syscallnames[af->event];            else if ( af->event >= MIN_TRUSTED_EVENT && af->event < MIN_TRUSTED_EVENT + N_TRUSTED_EVENTS )                eventp = trustedevent[af->event-MIN_TRUSTED_EVENT];            else if ( af->event >= MIN_SPECIAL && af->event <= MAX_SPECIAL )                eventp = special_event[af->event-MIN_SPECIAL];            else {                if ( af->flag == 0 ) af->flag = 1;                return(0);            }            for ( k = 0; (eventp[k] == RULE(i,event)[k]) && eventp[k]; k++ );            if ( (eventp[k] == '\0' && RULE(i,event)[k] == '\0') || RULE(i,event)[k] == '*' )                match = 1;        }        /* compare string params against rules; allow '*' wildcard */        if ( match ) {            if ( RULE(i,param)[0] == '*' ) match = 1;            else for ( match = j = 0; j < af->charp_indx; j++ ) {                for ( k = 0; (af->charparam[j][k] == RULE(i,param)[k]) &&                (k < af->charlen[j]); k++ );                if ( (k == af->charlen[j] && RULE(i,param)[k] == '\0')                || RULE(i,param)[k] == '*' ) {                    match = 1;                    break;                }            }        }        /* compare operation against rules for open()'s (using 1st intparam) */        if ( match && af->event == SYS_open )            match = (af->intparam[0] == RULE(i,oprtn)) || (RULE(i,oprtn) == -1);        if ( match ) return ( match );    }    return(0);}/* fetch header file and update a_proc structure and state; return sort status */int fetch_hdr ( logfile, start_str, sort )char *logfile;char *start_str;                    /* user specified start time */int  sort;                          /* 1: check sort status only */                                    /* 2: update sortflag in hdr */{    char logfilehdr[MAXPATHLEN];    struct a_proc *a_ptr;    long start_time;                /* start time from hdr file  */    long end_time;                  /* end time from header file */    char nextlog[MAXPATHLEN];       /* next audit log filename   */    int fd;    int i, j;    /* open first logfile header */    for ( i = 0; logfile[i] && i < MAXPATHLEN-5; i++ );    bcopy ( logfile, logfilehdr, i );    if ( strncmp ( &logfilehdr[i-2], ".Z", 2 ) == 0 ) i -= 2;    bcopy ( ".hdr\0", &logfilehdr[i], 5 );    if ( (fd = open ( logfilehdr, 2 )) == -1 ) return(0);    /* check/update sort status */    if ( sort == 2 ) {        write ( fd, &sort, sizeof(int) );        return(0);    }    read ( fd, &sort_flag, sizeof(sort_flag) );    if ( sort == 1 ) return(sort_flag);    /* open file which corresponds to user specified time */    if ( *start_str ) {        j = 0;        do {            read ( fd, &start_time, sizeof(start_time) );            read ( fd, &end_time, sizeof(end_time) );            i = 0;            do {                read ( fd, &nextlog[i], 1 );            } while ( nextlog[i++] && i < MAXPATHLEN );            if ( start_time == 0 && end_time == 0 ) j = 1;            else if ( (match_time ( start_str, start_time ) >= 0) &&                (match_time ( start_str, end_time ) <= 0) ) j = 1;            /* get next logfile hdr */            else {                bcopy ( nextlog, logfile, i );                close(fd);                bcopy ( logfile, logfilehdr, i );                bcopy ( ".hdr\0", &logfilehdr[i-1], 5 );                if ( (fd = open ( logfilehdr, 0 )) == -1 ) return(0);            }        } while ( j == 0 );    }#define FETCHIT(obj,indx) \    read ( fd, &indx, sizeof(int) ); \    if ( indx ) { \        obj = aud_mem_op ( indx, (char *)0, 0, 0 ); \        if ( obj ) read ( fd, obj, indx ); \        else lseek ( fd, indx, L_INCR ); \    }    /* read state information */    lseek ( fd, (sizeof start_time)*2+(sizeof sort_flag)+MAXPATHLEN, L_SET );    for ( ;; ) {        a_ptr = aud_mem_proc ( 1, (struct a_proc *)0, -1, -1, 0 );        if ( a_ptr == (struct a_proc *)-1 ) break;        if ( (i = read ( fd, (char *)a_ptr, A_PROC_HDR_SIZ )) != A_PROC_HDR_SIZ ) break;        FETCHIT ( a_ptr->cwd, i );        FETCHIT ( a_ptr->root, i );        FETCHIT ( a_ptr->username, i );        for ( i = 0; i < _NFILE; i++ ) {            FETCHIT ( a_ptr->fd_nm[i], j );        }    }    close ( fd );    return(0);}/* fetch records matching stated conditions; return record ptr; update rec_len */char *fetch_matching_rec ( audit_fields, selectn, cnt, flag, rec_len, fd_p )struct audit_fields *audit_fields;  /* audit record fields    */struct selectn *selectn;            /* selection criteria     */int *cnt;                           /* # records processed    */int flag;                           /* misc options           */int *rec_len;                       /* length of record       */int *fd_p;                          /* data file descriptor   */{    static char logfile[MAXPATHLEN];    struct stat sbuf;    char *rec_ptr;    int match;    static int get_time = 1;    static long time_l;    static int cnt_l = 0;           /* # records processed in current log */    static int auditd_event = 0;    /* auditd audit log event occurred    */    int pos1, pos2;    int i;    /* open auditlog datafile and header; use timestamp if provided */    if ( *fd_p == 0 ) {        for ( i = 0; selectn->logfile[i]; i++ );        bcopy ( selectn->logfile, logfile, i+1 );        fetch_hdr ( logfile, selectn->time_start, 0 );        if ( stat ( logfile, &sbuf ) == -1 ) {            for ( i = 0; logfile[i]; i++ );            if ( strncmp ( &logfile[i-2], ".Z", 2 ) )                bcopy ( ".Z\0", &logfile[i], 3 );        }        compress ( 0, logfile );        if ( (*fd_p = open ( logfile, 0 )) == -1 ) {            fprintf ( stderr, "failed to open %s\n", logfile );            return((char *)-1);        }        cnt_l = 0;        if ( flag & FLAG_SORT ) audit_sort ( logfile );    }    if ( *fd_p == -1 ) return((char *)-1);    /* fetch records until selection criteria satisfied */    do {        init_audit_fields ( audit_fields );        rec_ptr = fetch_rec ( fd_p, rec_len, audit_fields, flag&FLAG_FOLLOW, cnt_l );        if ( rec_ptr == (char *)-1 ) {            if ( (flag&FLAG_OVERRIDE) == 0 ) compress ( 1, (char *)0 );            return ( (char *)-1 );        }        (*cnt)++; cnt_l++;        /* allow partial records after auditd event */        if ( auditd_event && audit_fields->flag == 2 ) audit_fields->flag = 0;        /* parse data; maintain process state */        parse_rec ( rec_ptr, *rec_len, audit_fields );        state_maint ( audit_fields );        /* find records matching input params; deselect according to ruleset */        match = match_rec ( audit_fields, selectn );        if ( ruleno && match ) match = !deselect ( audit_fields, ruleno );        /* save first timestamp for logfile hdr */        if ( get_time ) {            time_l = audit_fields->timeval.tv_sec;            get_time = 0;        }        /* check for auditd change log messages */        if ( (audit_fields->event == AUDIT_LOG_CHANGE) && ((flag&FLAG_OVERRIDE) == 0) ) {            pos1 = tell ( *fd_p );            lseek ( *fd_p, 0, L_XTND );            pos2 = tell ( *fd_p );            if ( pos1 == pos2 ) {                change_log ( fd_p, logfile, time_l, audit_fields );                if ( flag & FLAG_SORT ) audit_sort ( logfile );                cnt_l = 0;                get_time = 1;            }            else lseek ( *fd_p, pos1, L_SET );        }        if ( (audit_fields->event == AUDIT_LOG_CREAT) ||        (audit_fields->event == AUDIT_LOG_OVERWRITE) ||        (audit_fields->event == AUDIT_SUSPEND) ||        (audit_fields->event == AUDIT_SHUTDOWN) ||        (audit_fields->event == AUDIT_XMIT_FAIL) )            auditd_event = 1;        else auditd_event = 0;    } while ( match == 0 );    return ( rec_ptr );}/* read audit record; return ptr; modify length */char *fetch_rec ( fd_p, rec_len, af, follow, cnt )int *fd_p;                  /* audit file descriptor             */int *rec_len;               /* length of audit record - returned */struct audit_fields *af;    /* audit record fields               */int follow;                 /* like tail -f                      */int cnt;                    /* # records processed from *fd_p    */{    static char buf[AUD_BUF_SIZ];    static int recvr = 0;    char rec_len_buf[sizeof *rec_len];    char token;    int ptr = 0;    int i, j;    /* read record length */    do {        /* find first LENGTH token */        do {            j = read ( *fd_p, &token, sizeof token );            if ( token != T_LENGTH && j == sizeof token ) af->flag = 2;            /* attempt recovery of split record */            /* assumes first record is remainder of split record */            if ( recvr && cnt == 0 ) {                recvr = 0;                if ( recover ( 1, buf, *rec_len, fd_p ) == 0 )                    af->flag = 7;                return ( buf );            }        } while ( ((j == 0) && follow) || ((j > 0) && (token != T_LENGTH)) );        if ( j <= 0 ) return ( (char *)-1 );        bcopy ( &token, buf, sizeof token );        /* read length */        i = 0;        do {            j = read ( *fd_p, &rec_len_buf[i], 1 );            if ( j ) i++;        } while ( ((j == 0) && follow) || ((j > 0) && (i < sizeof *rec_len)) );        bcopy ( rec_len_buf, rec_len, sizeof(int) );        if ( j <= 0 ) return ( (char *)-1 );        if ( (*rec_len < 0) | (*rec_len >= AUD_BUF_SIZ) ) af->flag = 3;    } while ( (*rec_len < 0) || (*rec_len >= AUD_BUF_SIZ) );    bcopy ( rec_len, &buf[sizeof token], sizeof *rec_len );    /* read next char into start of data area */    do {        j = read ( *fd_p, &buf[sizeof *rec_len + sizeof token], sizeof token );    } while ( (j == 0) && follow );    if ( j <= 0 ) return ( (char *)-1 );    /* if next char was another LENGTH token, read length again */    if ( buf[sizeof *rec_len + sizeof token] == T_LENGTH ) {        i = 0;        do {            j = read ( *fd_p, &rec_len_buf[i], 1 );            if ( j ) i++;        } while ( ((j == 0) && follow) || ((j > 0) && (i < sizeof *rec_len)) );        bcopy ( rec_len_buf, rec_len, sizeof(int) );        if ( j <= 0 ) return ( (char *)-1 );        bcopy ( rec_len, &buf[sizeof token], sizeof *rec_len );    }    else ptr++;    /* read data */    if ( (*rec_len < 0) || (*rec_len >= AUD_BUF_SIZ) ) {        af->flag = 4;        return ( buf );    };    i = *rec_len - (sizeof *rec_len + sizeof token + ptr);    j = 0;    do {        j += read ( *fd_p, &buf[ptr + sizeof *rec_len + sizeof token + j], i-j );    } while ( (j < i) && follow );    if ( j < i ) return ( (char *)-1 );    /* consistency check */    bcopy ( &buf[*rec_len - (sizeof *rec_len)], &i, sizeof(int) );    if ( i != *rec_len && af->flag != 7 ) {        i = recover ( 0, buf, *rec_len, fd_p );        if ( i == AUDIT_LOG_CHANGE ) {            af->flag = 8;            recvr = 1;        }        else if ( i == AUDIT_SUSPEND ) af->flag = 9;        else if ( i == AUDIT_LOG_CREAT ) af->flag = 9;        else if ( i == AUDIT_LOG_OVERWRITE ) af->flag = 9;        else if ( i == AUDIT_SHUTDOWN ) af->flag = 9;        else if ( i == AUDIT_XMIT_FAIL ) af->flag = 9;        else af->flag = 5;        *rec_len = 0;     }    return ( buf );}/* return hostname associated with ipaddr */char *gethost_l ( ipaddr )long ipaddr;{    struct hostent *hostp;    static long ipaddr_prev = 0;    static char h_name_prev[128];    int i;    if ( ipaddr_prev && ipaddr == ipaddr_prev ) return ( h_name_prev );    if ( (hostp = gethostbyaddr ( (char *)&ipaddr, sizeof(long), AF_INET )) == (struct hostent *)0 )        return ( (char *)0 );    /* save hostname, ipaddr for next iteration */    ipaddr_prev = ipaddr;    for ( i = 0; hostp->h_name[i]; i++ );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?