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