new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / rootcheck / util / ads_dump.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <dirent.h>
14 #include <windows.h>
15
16 /* ads_dump
17  * Dumps every NTFS ADS found in a directory (recursive)
18  */
19
20 /* Prototypes */
21 int os_get_streams(char *full_path);
22 int read_sys_dir(char *dir_name);
23 int read_sys_file(char *file_name);
24
25 /* Global variables */
26 int ads_found = 0;
27
28
29 /* Print out streams of a file */
30 int os_get_streams(char *full_path)
31 {
32     HANDLE file_h;
33     WIN32_STREAM_ID sid;
34     void *context = NULL;
35     char stream_name[MAX_PATH + 1];
36     char final_name[MAX_PATH + 1];
37     DWORD dwRead, shs, dw1, dw2;
38
39     /* Open file */
40     file_h = CreateFile(full_path,
41                         GENERIC_READ,
42                         FILE_SHARE_READ,
43                         NULL,
44                         OPEN_EXISTING,
45                         FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS,
46                         NULL);
47
48     if (file_h == INVALID_HANDLE_VALUE) {
49         return 0;
50     }
51
52     /* Zero memory */
53     ZeroMemory(&sid, sizeof(WIN32_STREAM_ID));
54
55     /* Get stream header size -- should be 20 bytes */
56     shs = (LPBYTE)&sid.cStreamName - (LPBYTE)&sid + sid.dwStreamNameSize;
57
58     while (1) {
59         if (BackupRead(file_h, (LPBYTE) &sid, shs, &dwRead,
60                        FALSE, FALSE, &context) == 0) {
61             break;
62         }
63         if (dwRead == 0) {
64             break;
65         }
66
67         stream_name[0] = '\0';
68         stream_name[MAX_PATH] = '\0';
69         if (BackupRead(file_h, (LPBYTE)stream_name,
70                        sid.dwStreamNameSize,
71                        &dwRead, FALSE, FALSE, &context)) {
72             if (dwRead != 0) {
73                 char *tmp_pt;
74                 snprintf(final_name, MAX_PATH, "%s%S", full_path,
75                          (WCHAR *)stream_name);
76                 tmp_pt = strrchr(final_name, ':');
77                 if (tmp_pt) {
78                     *tmp_pt = '\0';
79                 }
80                 printf("Found NTFS ADS: '%s' \n", final_name);
81                 ads_found = 1;
82             }
83         }
84
85         /* Get next */
86         if (!BackupSeek(file_h, sid.Size.LowPart, sid.Size.HighPart,
87                         &dw1, &dw2, &context)) {
88             break;
89         }
90     }
91
92     CloseHandle(file_h);
93     return (0);
94 }
95
96 int read_sys_file(char *file_name)
97 {
98     struct stat statbuf;
99
100     /* Get streams */
101     os_get_streams(file_name);
102     if (stat(file_name, &statbuf) < 0) {
103         return (0);
104     }
105
106     /* If directory, read the directory */
107     else if (S_ISDIR(statbuf.st_mode)) {
108         return (read_sys_dir(file_name));
109     }
110
111     return (0);
112 }
113
114 int read_sys_dir(char *dir_name)
115 {
116     DIR *dp;
117     struct dirent *entry;
118     struct stat statbuf;
119
120     /* Get the number of nodes. The total number on opendir
121      * must be the same.
122      */
123     if (stat(dir_name, &statbuf) < 0) {
124         return (-1);
125     }
126
127     /* Must be a directory */
128     if (!S_ISDIR(statbuf.st_mode)) {
129         return (-1);
130     }
131
132     /* Open the directory given */
133     dp = opendir(dir_name);
134     if (!dp) {
135         return (-1);
136     }
137
138     /* Read every entry in the directory */
139     while ((entry = readdir(dp)) != NULL) {
140         char f_name[MAX_PATH + 2];
141
142         /* Ignore . and ..  */
143         if ((strcmp(entry->d_name, ".") == 0) ||
144                 (strcmp(entry->d_name, "..") == 0)) {
145             continue;
146         }
147
148         /* Create new file + path string */
149         snprintf(f_name, MAX_PATH + 1, "%s\\%s", dir_name, entry->d_name);
150
151         read_sys_file(f_name);
152     }
153
154     closedir(dp);
155
156     return (0);
157 }
158
159 int main(int argc, char **argv)
160 {
161     printf("%s: NTFS ADS dumper (GPL v2)\n", argv[0]);
162     printf("by Daniel B. Cid - dcid at ossec.net\n\n");
163
164     /* Print every NTFS ADS found */
165     if (argc < 2) {
166         printf("%s dir\n", argv[0]);
167         exit(1);
168     }
169
170     /* Get streams */
171     read_sys_file(argv[1]);
172
173     if (ads_found == 0) {
174         printf("No NTFS ADS found.\n");
175     }
176     return (0);
177 }
178