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