new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / rootcheck / check_rc_dev.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 #ifndef WIN32
11 #include "shared.h"
12 #include "rootcheck.h"
13
14 /* Prototypes */
15 static int read_dev_file(const char *file_name);
16 static int read_dev_dir(const char *dir_name);
17
18 /* Global variables */
19 static int _dev_errors;
20 static int _dev_total;
21
22
23 static int read_dev_file(const char *file_name)
24 {
25     struct stat statbuf;
26
27     if (lstat(file_name, &statbuf) < 0) {
28         return (-1);
29     }
30
31     /* Process directories recursively */
32     if (S_ISDIR(statbuf.st_mode)) {
33 #ifdef DEBUG
34         verbose("%s: Reading dir: %s\n", ARGV0, file_name);
35 #endif
36         return (read_dev_dir(file_name));
37     }
38
39     else if (S_ISREG(statbuf.st_mode)) {
40         char op_msg[OS_SIZE_1024 + 1];
41
42         snprintf(op_msg, OS_SIZE_1024, "File '%s' present on /dev."
43                  " Possible hidden file.", file_name);
44         notify_rk(ALERT_SYSTEM_CRIT, op_msg);
45
46         _dev_errors++;
47     }
48
49     return (0);
50 }
51
52 static int read_dev_dir(const char *dir_name)
53 {
54     int i;
55     DIR *dp;
56     struct dirent *entry;
57
58     /* When will these people learn that /dev is not
59      * meant to store log files or other kind of texts?
60      */
61     const char *(ignore_dev[]) = {"MAKEDEV", "README.MAKEDEV",
62                                   "MAKEDEV.README", ".udevdb",
63                                   ".udev.tdb", ".initramfs-tools",
64                                   "MAKEDEV.local", ".udev", ".initramfs",
65                                   "oprofile", "fd", "cgroup",
66 #ifdef SOLARIS
67                                   ".devfsadm_dev.lock",
68                                   ".devlink_db_lock",
69                                   ".devlink_db",
70                                   ".devfsadm_daemon.lock",
71                                   ".devfsadm_deamon.lock",
72                                   ".devfsadm_synch_door",
73                                   ".zone_reg_door",
74 #endif
75                                   NULL
76                                  };
77
78     /* Full path ignore */
79     const char *(ignore_dev_full_path[]) = {"/dev/shm/sysconfig",
80                                             "/dev/bus/usb/.usbfs",
81                                             "/dev/shm",
82                                             "/dev/gpmctl",
83                                             NULL
84                                            };
85
86     if (dir_name == NULL || strlen(dir_name) > PATH_MAX) {
87         merror("%s: Invalid directory given.", ARGV0);
88         return (-1);
89     }
90
91     /* Open directory */
92     dp = opendir(dir_name);
93     if (!dp) {
94         return (-1);
95     }
96
97     /* Iterate over all files in the directory */
98     while ((entry = readdir(dp)) != NULL) {
99         char f_name[PATH_MAX + 2];
100
101         /* Ignore . and ..  */
102         if (strcmp(entry->d_name, ".") == 0 ||
103                 strcmp(entry->d_name, "..") == 0) {
104             continue;
105         }
106
107         _dev_total++;
108
109         /* Do not look for the ignored files */
110         for (i = 0; ignore_dev[i] != NULL; i++) {
111             if (strcmp(ignore_dev[i], entry->d_name) == 0) {
112                 break;
113             }
114         }
115         if (ignore_dev[i] != NULL) {
116             continue;
117         }
118
119         f_name[PATH_MAX + 1] = '\0';
120         snprintf(f_name, PATH_MAX + 1, "%s/%s", dir_name, entry->d_name);
121
122         /* Do not look for the full ignored files */
123         for (i = 0; ignore_dev_full_path[i] != NULL; i++) {
124             if (strcmp(ignore_dev_full_path[i], f_name) == 0) {
125                 break;
126             }
127         }
128
129         /* Check against the full path */
130         if (ignore_dev_full_path[i] != NULL) {
131             continue;
132         }
133
134         /* Found a non-ignored entry in the directory, so process it */
135         read_dev_file(f_name);
136     }
137
138     closedir(dp);
139     return (0);
140 }
141
142 void check_rc_dev(const char *basedir)
143 {
144     char file_path[OS_SIZE_1024 + 1];
145
146     _dev_total = 0, _dev_errors = 0;
147     debug1("%s: DEBUG: Starting on check_rc_dev", ARGV0);
148
149     snprintf(file_path, OS_SIZE_1024, "%s/dev", basedir);
150
151     read_dev_dir(file_path);
152     if (_dev_errors == 0) {
153         char op_msg[OS_SIZE_1024 + 1];
154         snprintf(op_msg, OS_SIZE_1024, "No problem detected on the /dev "
155                  "directory. Analyzed %d files",
156                  _dev_total);
157         notify_rk(ALERT_OK, op_msg);
158     }
159
160     return;
161 }
162
163 #else
164
165 /* Not relevant on Windows */
166 void check_rc_dev(__attribute__((unused)) char *basedir)
167 {
168     return;
169 }
170
171 #endif /* WIN32 */
172