-/* @(#) $Id: run_check.c,v 1.49 2009/11/05 15:15:14 dcid Exp $ */
-
-/* Copyright (C) 2009 Trend Micro Inc.
+/* Copyright (C) 2010 Trend Micro Inc.
* All right reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
- * License (version 3) as published by the FSF - Free Software
+ * License (version 2) as published by the FSF - Free Software
* Foundation
*/
-
/* SCHED_BATCH is Linux specific and is only picked up with _GNU_SOURCE */
#ifdef __linux__
- #define _GNU_SOURCE
- #include <sched.h>
+#define _GNU_SOURCE
+#include <sched.h>
+#endif
+#ifdef WIN32
+#include <winsock2.h>
+#include <aclapi.h>
+#include <sddl.h>
#endif
#include "shared.h"
#include "os_crypto/md5/md5_op.h"
#include "os_crypto/sha1/sha1_op.h"
#include "os_crypto/md5_sha1/md5_sha1_op.h"
-
#include "rootcheck/rootcheck.h"
-
-/** Prototypes **/
-int c_read_file(char *file_name, char *oldsum, char *newsum);
+/* Prototypes */
+static void send_sk_db(void);
-/* Send syscheck message.
- * Send a message related to syscheck change/addition.
- */
-int send_syscheck_msg(char *msg)
+/* Send a message related to syscheck change/addition */
+int send_syscheck_msg(const char *msg)
{
- if(SendMSG(syscheck.queue, msg, SYSCHECK, SYSCHECK_MQ) < 0)
- {
+ if (SendMSG(syscheck.queue, msg, SYSCHECK, SYSCHECK_MQ) < 0) {
merror(QUEUE_SEND, ARGV0);
- if((syscheck.queue = StartMQ(DEFAULTQPATH,WRITE)) < 0)
- {
+ if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
}
- /* If we reach here, we can try to send it again */
+ /* Try to send it again */
SendMSG(syscheck.queue, msg, SYSCHECK, SYSCHECK_MQ);
}
-
- return(0);
+ return (0);
}
-
-
-/* Send rootcheck message.
- * Send a message related to rootcheck change/addition.
- */
-int send_rootcheck_msg(char *msg)
+/* Send a message related to rootcheck change/addition */
+int send_rootcheck_msg(const char *msg)
{
- if(SendMSG(syscheck.queue, msg, ROOTCHECK, ROOTCHECK_MQ) < 0)
- {
+ if (SendMSG(syscheck.queue, msg, ROOTCHECK, ROOTCHECK_MQ) < 0) {
merror(QUEUE_SEND, ARGV0);
- if((syscheck.queue = StartMQ(DEFAULTQPATH,WRITE)) < 0)
- {
+ if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
}
- /* If we reach here, we can try to send it again */
+ /* Try to send it again */
SendMSG(syscheck.queue, msg, ROOTCHECK, ROOTCHECK_MQ);
}
-
- return(0);
+ return (0);
}
-
-/* Sends syscheck db to the server.
- */
-void send_sk_db()
+/* Send syscheck db to the server */
+static void send_sk_db()
{
- char buf[MAX_LINE +1];
- int file_count = 0;
-
- buf[MAX_LINE] = '\0';
-
- if(fseek(syscheck.fp, 0, SEEK_SET) == -1)
- {
- ErrorExit(FSEEK_ERROR, ARGV0, "syscheck_db");
- }
-
-
- /* Sending scan start message */
- if(syscheck.dir[0])
- {
+ /* Send scan start message */
+ if (syscheck.dir[0]) {
merror("%s: INFO: Starting syscheck scan (forwarding database).", ARGV0);
send_rootcheck_msg("Starting syscheck scan.");
- }
- else
- {
- sleep(syscheck.tsleep +10);
+ } else {
return;
}
-
-
-
- while(fgets(buf,MAX_LINE, syscheck.fp) != NULL)
- {
- if((buf[0] != '#') && (buf[0] != ' ') && (buf[0] != '\n'))
- {
- char *n_buf;
-
- /* Removing the \n before sending to the analysis server */
- n_buf = strchr(buf,'\n');
- if(n_buf == NULL)
- continue;
-
- *n_buf = '\0';
-
-
- /* First 6 characters are for internal use */
- n_buf = buf;
- n_buf+=6;
-
- send_syscheck_msg(n_buf);
-
-
- /* A count and a sleep to avoid flooding the server.
- * Time or speed are not requirements in here
- */
- file_count++;
-
-
- /* sleep X every Y files */
- if(file_count >= syscheck.sleep_after)
- {
- sleep(syscheck.tsleep);
- file_count = 0;
- }
- }
- }
+ create_db();
- /* Sending scan ending message */
- sleep(syscheck.tsleep +10);
+ /* Send scan ending message */
+ sleep(syscheck.tsleep + 10);
- if(syscheck.dir[0])
- {
+ if (syscheck.dir[0]) {
merror("%s: INFO: Ending syscheck scan (forwarding database).", ARGV0);
send_rootcheck_msg("Ending syscheck scan.");
}
}
-
-
-/* start_daemon
- * Run periodicaly the integrity checking
- */
+/* Periodically run the integrity checker */
void start_daemon()
{
int day_scanned = 0;
int curr_day = 0;
-
time_t curr_time = 0;
-
time_t prev_time_rk = 0;
time_t prev_time_sk = 0;
-
char curr_hour[12];
-
struct tm *p;
-
- /* To be used by select. */
- #ifdef USEINOTIFY
+#ifdef INOTIFY_ENABLED
+ /* To be used by select */
struct timeval selecttime;
fd_set rfds;
- #endif
-
-
- /*
- * SCHED_BATCH forces the kernel to assume this is a cpu intensive
- * process
- * and gives it a lower priority. This keeps ossec-syscheckd
- * from reducing
- * the interactity of an ssh session when checksumming large files.
- * This is available in kernel flavors >= 2.6.16
+#endif
+
+ /* SCHED_BATCH forces the kernel to assume this is a cpu intensive
+ * process and gives it a lower priority. This keeps ossec-syscheckd
+ * from reducing the interactivity of an ssh session when checksumming
+ * large files. This is available in kernel flavors >= 2.6.16.
*/
- #ifdef SCHED_BATCH
+#ifdef SCHED_BATCH
struct sched_param pri;
int status;
-
+
pri.sched_priority = 0;
status = sched_setscheduler(0, SCHED_BATCH, &pri);
-
+
debug1("%s: Setting SCHED_BATCH returned: %d", ARGV0, status);
- #endif
-
-
- #ifdef DEBUG
- verbose("%s: Starting daemon ..",ARGV0);
- #endif
-
-
-
+#endif
+
+#ifdef DEBUG
+ verbose("%s: Starting daemon ..", ARGV0);
+#endif
+
/* Some time to settle */
memset(curr_hour, '\0', 12);
sleep(syscheck.tsleep * 10);
-
-
- /* If the scan time/day is set, reset the
- * syscheck.time/rootcheck.time
+ /* If the scan time/day is set, reset the
+ * syscheck.time/rootcheck.time
*/
- if(syscheck.scan_time || syscheck.scan_day)
- {
- /* At least once a week. */
+ if (syscheck.scan_time || syscheck.scan_day) {
+ /* At least once a week */
syscheck.time = 604800;
rootcheck.time = 604800;
}
-
/* Will create the db to store syscheck data */
- if(syscheck.scan_on_start)
- {
- create_db(1);
- fflush(syscheck.fp);
-
- sleep(syscheck.tsleep * 60);
+ if (syscheck.scan_on_start) {
+ sleep(syscheck.tsleep * 15);
send_sk_db();
- }
- else
- {
+
+#ifdef WIN32
+ /* Check for registry changes on Windows */
+ os_winreg_check();
+#endif
+ /* Send database completed message */
+ send_syscheck_msg(HC_SK_DB_COMPLETED);
+ debug2("%s: DEBUG: Sending database completed message.", ARGV0);
+
+ } else {
prev_time_rk = time(0);
}
-
-
/* Before entering in daemon mode itself */
prev_time_sk = time(0);
sleep(syscheck.tsleep * 10);
-
/* If the scan_time or scan_day is set, we need to handle the
* current day/time on the loop.
*/
- if(syscheck.scan_time || syscheck.scan_day)
- {
- curr_time = time(0);
+ if (syscheck.scan_time || syscheck.scan_day) {
+ curr_time = time(0);
p = localtime(&curr_time);
-
/* Assign hour/min/sec values */
snprintf(curr_hour, 9, "%02d:%02d:%02d",
- p->tm_hour,
- p->tm_min,
- p->tm_sec);
-
+ p->tm_hour,
+ p->tm_min,
+ p->tm_sec);
curr_day = p->tm_mday;
-
-
- if(syscheck.scan_time && syscheck.scan_day)
- {
- if((OS_IsAfterTime(curr_hour, syscheck.scan_time)) &&
- (OS_IsonDay(p->tm_wday, syscheck.scan_day)))
- {
+ if (syscheck.scan_time && syscheck.scan_day) {
+ if ((OS_IsAfterTime(curr_hour, syscheck.scan_time)) &&
+ (OS_IsonDay(p->tm_wday, syscheck.scan_day))) {
day_scanned = 1;
}
- }
-
- else if(syscheck.scan_time)
- {
- if(OS_IsAfterTime(curr_hour, syscheck.scan_time))
- {
+ } else if (syscheck.scan_time) {
+ if (OS_IsAfterTime(curr_hour, syscheck.scan_time)) {
day_scanned = 1;
}
- }
- else if(syscheck.scan_day)
- {
- if(OS_IsonDay(p->tm_wday, syscheck.scan_day))
- {
+ } else if (syscheck.scan_day) {
+ if (OS_IsonDay(p->tm_wday, syscheck.scan_day)) {
day_scanned = 1;
}
}
}
-
- #if defined (USEINOTIFY) || defined (WIN32)
- if(syscheck.realtime && (syscheck.realtime->fd >= 0))
- verbose("%s: INFO: Starting real time file monitoring.", ARGV0);
- #endif
-
-
- /* Checking every SYSCHECK_WAIT */
- while(1)
- {
+ /* Check every SYSCHECK_WAIT */
+ while (1) {
int run_now = 0;
curr_time = time(0);
-
- /* Checking if syscheck should be restarted, */
+ /* Check if syscheck should be restarted */
run_now = os_check_restart_syscheck();
-
- /* Checking if a day_time or scan_time is set. */
- if(syscheck.scan_time || syscheck.scan_day)
- {
+ /* Check if a day_time or scan_time is set */
+ if (syscheck.scan_time || syscheck.scan_day) {
p = localtime(&curr_time);
-
- /* Day changed. */
- if(curr_day != p->tm_mday)
- {
+ /* Day changed */
+ if (curr_day != p->tm_mday) {
day_scanned = 0;
curr_day = p->tm_mday;
}
-
-
- /* Checking for the time of the scan. */
- if(!day_scanned && syscheck.scan_time && syscheck.scan_day)
- {
- if((OS_IsAfterTime(curr_hour, syscheck.scan_time)) &&
- (OS_IsonDay(p->tm_wday, syscheck.scan_day)))
- {
+
+ /* Check for the time of the scan */
+ if (!day_scanned && syscheck.scan_time && syscheck.scan_day) {
+ /* Assign hour/min/sec values */
+ snprintf(curr_hour, 9, "%02d:%02d:%02d",
+ p->tm_hour, p->tm_min, p->tm_sec);
+
+ if ((OS_IsAfterTime(curr_hour, syscheck.scan_time)) &&
+ (OS_IsonDay(p->tm_wday, syscheck.scan_day))) {
day_scanned = 1;
run_now = 1;
}
- }
-
- else if(!day_scanned && syscheck.scan_time)
- {
+ } else if (!day_scanned && syscheck.scan_time) {
/* Assign hour/min/sec values */
- snprintf(curr_hour, 9, "%02d:%02d:%02d",
- p->tm_hour, p->tm_min, p->tm_sec);
+ snprintf(curr_hour, 9, "%02d:%02d:%02d",
+ p->tm_hour, p->tm_min, p->tm_sec);
- if(OS_IsAfterTime(curr_hour, syscheck.scan_time))
- {
+ if (OS_IsAfterTime(curr_hour, syscheck.scan_time)) {
run_now = 1;
day_scanned = 1;
}
- }
-
- /* Checking for the day of the scan. */
- else if(!day_scanned && syscheck.scan_day)
- {
- if(OS_IsonDay(p->tm_wday, syscheck.scan_day))
- {
+ } else if (!day_scanned && syscheck.scan_day) {
+ /* Check for the day of the scan */
+ if (OS_IsonDay(p->tm_wday, syscheck.scan_day)) {
run_now = 1;
day_scanned = 1;
}
}
}
-
-
-
- /* If time elapsed is higher than the rootcheck_time,
- * run it.
- */
- if(syscheck.rootcheck)
- {
- if(((curr_time - prev_time_rk) > rootcheck.time) || run_now)
- {
+
+ /* If time elapsed is higher than the rootcheck_time, run it */
+ if (syscheck.rootcheck) {
+ if (((curr_time - prev_time_rk) > rootcheck.time) || run_now) {
run_rk_check();
prev_time_rk = time(0);
}
}
-
- /* If time elapsed is higher than the syscheck time,
- * run syscheck time.
- */
- if(((curr_time - prev_time_sk) > syscheck.time) || run_now)
- {
- /* We need to create the db, if scan on start is not set. */
- if(syscheck.scan_on_start == 0)
- {
- create_db(1);
- fflush(syscheck.fp);
-
+ /* If time elapsed is higher than the syscheck time, run syscheck time */
+ if (((curr_time - prev_time_sk) > syscheck.time) || run_now) {
+ if (syscheck.scan_on_start == 0) {
+ /* Need to create the db if scan on start is not set */
sleep(syscheck.tsleep * 10);
send_sk_db();
sleep(syscheck.tsleep * 10);
syscheck.scan_on_start = 1;
- }
-
-
- else
- {
- /* Sending scan start message */
- if(syscheck.dir[0])
- {
+ } else {
+ /* Send scan start message */
+ if (syscheck.dir[0]) {
merror("%s: INFO: Starting syscheck scan.", ARGV0);
send_rootcheck_msg("Starting syscheck scan.");
}
-
-
- #ifdef WIN32
- /* Checking for registry changes on Windows */
+#ifdef WIN32
+ /* Check for registry changes on Windows */
os_winreg_check();
- #endif
-
-
- check_db();
-
-
- /* Set syscheck.fp to the begining of the file */
- fseek(syscheck.fp, 0, SEEK_SET);
-
-
- /* Checking for changes */
- run_check();
+#endif
+ /* Check for changes */
+ run_dbcheck();
}
-
- /* Sending scan ending message */
+ /* Send scan ending message */
sleep(syscheck.tsleep + 20);
- if(syscheck.dir[0])
- {
+ if (syscheck.dir[0]) {
merror("%s: INFO: Ending syscheck scan.", ARGV0);
send_rootcheck_msg("Ending syscheck scan.");
}
-
-
- /* Sending database completed message */
+ /* Send database completed message */
send_syscheck_msg(HC_SK_DB_COMPLETED);
debug2("%s: DEBUG: Sending database completed message.", ARGV0);
-
prev_time_sk = time(0);
- }
-
+ }
- #ifdef USEINOTIFY
- if(syscheck.realtime && (syscheck.realtime->fd >= 0))
- {
+#ifdef INOTIFY_ENABLED
+ if (syscheck.realtime && (syscheck.realtime->fd >= 0)) {
selecttime.tv_sec = SYSCHECK_WAIT;
selecttime.tv_usec = 0;
/* zero-out the fd_set */
FD_ZERO (&rfds);
-
FD_SET(syscheck.realtime->fd, &rfds);
- run_now = select(syscheck.realtime->fd + 1, &rfds,
+ run_now = select(syscheck.realtime->fd + 1, &rfds,
NULL, NULL, &selecttime);
- if(run_now < 0)
- {
+ if (run_now < 0) {
merror("%s: ERROR: Select failed (for realtime fim).", ARGV0);
sleep(SYSCHECK_WAIT);
- }
- else if(run_now == 0)
- {
- /* Timeout. */
- }
- else if (FD_ISSET (syscheck.realtime->fd, &rfds))
- {
+ } else if (run_now == 0) {
+ /* Timeout */
+ } else if (FD_ISSET (syscheck.realtime->fd, &rfds)) {
realtime_process();
}
- }
- else
- {
+ } else {
sleep(SYSCHECK_WAIT);
}
-
- #elif WIN32
- if(syscheck.realtime && (syscheck.realtime->fd >= 0))
- {
- run_now = WaitForSingleObjectEx(syscheck.realtime->evt, SYSCHECK_WAIT * 1000, TRUE);
- if(run_now == WAIT_FAILED)
- {
+#elif defined(WIN32)
+ if (syscheck.realtime && (syscheck.realtime->fd >= 0)) {
+ if (WaitForSingleObjectEx(syscheck.realtime->evt, SYSCHECK_WAIT * 1000, TRUE) == WAIT_FAILED) {
merror("%s: ERROR: WaitForSingleObjectEx failed (for realtime fim).", ARGV0);
sleep(SYSCHECK_WAIT);
- }
- else
- {
+ } else {
sleep(1);
}
- }
- else
- {
+ } else {
sleep(SYSCHECK_WAIT);
}
-
-
- #else
+#else
sleep(SYSCHECK_WAIT);
- #endif
- }
-}
-
-
-/* run_check: v0.1
- * Read the database and check if the binary has changed
- */
-void run_check()
-{
- char c_sum[256 +2];
- char alert_msg[912 +2];
- char buf[MAX_LINE +2];
- int file_count = 0;
-
-
- /* Cleaning buffer */
- memset(buf, '\0', MAX_LINE +1);
- memset(alert_msg, '\0', 912 +1);
- memset(c_sum, '\0', 256 +1);
-
- /* fgets garantee the null termination */
- while(fgets(buf, MAX_LINE, syscheck.fp) != NULL)
- {
- /* Buf should be in the following format:
- * header checksum file_name (checksum space filename)
- */
- char *n_file; /* file read from the db */
- char *n_sum; /* md5sum read from the db */
- char *tmp_c; /* tmp_char */
-
-
- /* Avoiding wrong formats in the database. Alert about them */
- if(buf[0] == '#' || buf[0] == ' ' || buf[0] == '\n')
- {
- merror("%s: Invalid entry in the integrity database: '%s'",
- ARGV0, buf);
- continue;
- }
-
- /* Adding a sleep in here -- avoid floods and extreme CPU usage
- * on the client side -- speed not necessary
- */
- file_count++;
- if(file_count >= (syscheck.sleep_after))
- {
- sleep(syscheck.tsleep);
- file_count = 0;
- }
-
-
- /* Finding the file name */
- n_file = strchr(buf, ' ');
- if(n_file == NULL)
- {
- merror("%s: Invalid entry in the integrity check database.",ARGV0);
- continue;
- }
-
- /* Zeroing the ' ' and messing up with buf */
- *n_file = '\0';
-
-
- /* Setting n_file to the begining of the file name */
- n_file++;
-
-
- /* Removing the '\n' if present and setting it to \0 */
- tmp_c = strchr(n_file,'\n');
- if(tmp_c)
- {
- *tmp_c = '\0';
- }
-
-
- /* Setting n_sum to the begining of buf */
- n_sum = buf;
-
-
- /* Cleaning up c_sum */
- memset(c_sum, '\0', 16);
- c_sum[255] = '\0';
-
-
- /* If it returns < 0, we will already have alerted. */
- if(c_read_file(n_file, n_sum, c_sum) < 0)
- continue;
-
-
- if(strcmp(c_sum, n_sum+6) != 0)
- {
- /* Sending the new checksum to the analysis server */
- alert_msg[912 +1] = '\0';
- snprintf(alert_msg, 912, "%s %s", c_sum, n_file);
- send_syscheck_msg(alert_msg);
-
- continue;
- }
-
- /* FILE OK if reached here */
+#endif
}
}
-
-/* c_read_file
- * Read file information and return a pointer
- * to the checksum
- */
-int c_read_file(char *file_name, char *oldsum, char *newsum)
+/* Read file information and return a pointer to the checksum */
+int c_read_file(const char *file_name, const char *oldsum, char *newsum)
{
int size = 0, perm = 0, owner = 0, group = 0, md5sum = 0, sha1sum = 0;
-
+ int return_error = 0;
struct stat statbuf;
-
os_md5 mf_sum;
os_sha1 sf_sum;
-
- /* Cleaning sums */
+ /* Clean sums */
strncpy(mf_sum, "xxx", 4);
strncpy(sf_sum, "xxx", 4);
-
-
-
- /* Stating the file */
- #ifdef WIN32
- if(stat(file_name, &statbuf) < 0)
- #else
- if(lstat(file_name, &statbuf) < 0)
- #endif
+
+ /* Stat the file */
+#ifdef WIN32
+ return_error = (stat(file_name, &statbuf) < 0);
+#else
+ return_error = (lstat(file_name, &statbuf) < 0);
+#endif
+ if (return_error)
{
- char alert_msg[912 +2];
+ char alert_msg[PATH_MAX+4];
- alert_msg[912 +1] = '\0';
- snprintf(alert_msg, 912,"-1 %s", file_name);
+ alert_msg[PATH_MAX + 3] = '\0';
+ snprintf(alert_msg, PATH_MAX + 4, "-1 %s", file_name);
send_syscheck_msg(alert_msg);
- return(-1);
+ return (-1);
}
- /* Getting the old sum values */
+ /* Get the old sum values */
/* size */
- if(oldsum[0] == '+')
+ if (oldsum[0] == '+') {
size = 1;
+ }
/* perm */
- if(oldsum[1] == '+')
+ if (oldsum[1] == '+') {
perm = 1;
+ }
/* owner */
- if(oldsum[2] == '+')
- owner = 1;
-
+ if (oldsum[2] == '+') {
+ owner = 1;
+ }
+
/* group */
- if(oldsum[3] == '+')
+ if (oldsum[3] == '+') {
group = 1;
-
+ }
+
/* md5 sum */
- if(oldsum[4] == '+')
+ if (oldsum[4] == '+') {
md5sum = 1;
+ }
/* sha1 sum */
- if(oldsum[5] == '+')
+ if (oldsum[5] == '+') {
sha1sum = 1;
-
-
- /* Generating new checksum */
- #ifdef WIN32
- if(S_ISREG(statbuf.st_mode))
- #else
- if(S_ISREG(statbuf.st_mode))
- #endif
+ } else if (oldsum[5] == 's') {
+ sha1sum = 1;
+ } else if (oldsum[5] == 'n') {
+ sha1sum = 0;
+ }
+
+ /* Generate new checksum */
+ if (S_ISREG(statbuf.st_mode))
{
- if(sha1sum || md5sum)
- {
- /* Generating checksums of the file. */
- if(OS_MD5_SHA1_File(file_name, mf_sum, sf_sum) < 0)
- {
+ if (sha1sum || md5sum) {
+ /* Generate checksums of the file */
+ if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) {
strncpy(sf_sum, "xxx", 4);
strncpy(mf_sum, "xxx", 4);
}
}
}
- #ifndef WIN32
- /* If it is a link, we need to check if the actual file is valid. */
- else if(S_ISLNK(statbuf.st_mode))
- {
+#ifndef WIN32
+ /* If it is a link, check if the actual file is valid */
+ else if (S_ISLNK(statbuf.st_mode)) {
struct stat statbuf_lnk;
- if(stat(file_name, &statbuf_lnk) == 0)
- {
- if(S_ISREG(statbuf_lnk.st_mode))
- {
- if(sha1sum || md5sum)
- {
- /* Generating checksums of the file. */
- if(OS_MD5_SHA1_File(file_name, mf_sum, sf_sum) < 0)
- {
+ if (stat(file_name, &statbuf_lnk) == 0) {
+ if (S_ISREG(statbuf_lnk.st_mode)) {
+ if (sha1sum || md5sum) {
+ /* Generate checksums of the file */
+ if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) {
strncpy(sf_sum, "xxx", 4);
strncpy(mf_sum, "xxx", 4);
}
}
}
}
- #endif
-
+#endif
+
newsum[0] = '\0';
newsum[255] = '\0';
- snprintf(newsum,255,"%d:%d:%d:%d:%s:%s",
- size == 0?0:(int)statbuf.st_size,
- perm == 0?0:(int)statbuf.st_mode,
- owner== 0?0:(int)statbuf.st_uid,
- group== 0?0:(int)statbuf.st_gid,
- md5sum == 0?"xxx":mf_sum,
- sha1sum == 0?"xxx":sf_sum);
-
- return(0);
-}
+#ifndef WIN32
+ snprintf(newsum, 255, "%ld:%d:%d:%d:%s:%s",
+ size == 0 ? 0 : (long)statbuf.st_size,
+ perm == 0 ? 0 : (int)statbuf.st_mode,
+ owner == 0 ? 0 : (int)statbuf.st_uid,
+ group == 0 ? 0 : (int)statbuf.st_gid,
+ md5sum == 0 ? "xxx" : mf_sum,
+ sha1sum == 0 ? "xxx" : sf_sum);
+#else
+ HANDLE hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE) {
+ DWORD dwErrorCode = GetLastError();
+ char alert_msg[PATH_MAX+4];
+ alert_msg[PATH_MAX + 3] = '\0';
+ snprintf(alert_msg, PATH_MAX + 4, "CreateFile=%ld %s", dwErrorCode, file_name);
+ send_syscheck_msg(alert_msg);
+ return -1;
+ }
+
+ PSID pSidOwner = NULL;
+ PSECURITY_DESCRIPTOR pSD = NULL;
+ DWORD dwRtnCode = GetSecurityInfo(hFile, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD);
+ if (dwRtnCode != ERROR_SUCCESS) {
+ DWORD dwErrorCode = GetLastError();
+ CloseHandle(hFile);
+ char alert_msg[PATH_MAX+4];
+ alert_msg[PATH_MAX + 3] = '\0';
+ snprintf(alert_msg, PATH_MAX + 4, "GetSecurityInfo=%ld %s", dwErrorCode, file_name);
+ send_syscheck_msg(alert_msg);
+ return -1;
+ }
-/* EOF */
+ LPSTR szSID = NULL;
+ ConvertSidToStringSid(pSidOwner, &szSID);
+ char* st_uid = NULL;
+ if( szSID ) {
+ st_uid = (char *) calloc( strlen(szSID) + 1, 1 );
+ memcpy( st_uid, szSID, strlen(szSID) );
+ }
+ LocalFree(szSID);
+ CloseHandle(hFile);
+
+ snprintf(newsum, 255, "%ld:%d:%s:%d:%s:%s",
+ size == 0 ? 0 : (long)statbuf.st_size,
+ perm == 0 ? 0 : (int)statbuf.st_mode,
+ owner == 0 ? "0" : st_uid,
+ group == 0 ? 0 : (int)statbuf.st_gid,
+ md5sum == 0 ? "xxx" : mf_sum,
+ sha1sum == 0 ? "xxx" : sf_sum);
+
+ free(st_uid);
+#endif
+
+ return (0);
+}