new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / rootcheck / check_rc_readproc.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
12 #include "shared.h"
13 #include "rootcheck.h"
14
15 #define PROC 0
16 #define PID  1
17 #define TASK 2
18
19 /* Prototypes */
20 static int read_proc_file(const char *file_name, const char *pid, int position);
21 static int read_proc_dir(const char *dir_name, const char *pid, int position);
22
23 /* Global variables */
24 static int proc_pid_found;
25
26
27 static int read_proc_file(const char *file_name, const char *pid, int position)
28 {
29     struct stat statbuf;
30
31     if (lstat(file_name, &statbuf) < 0) {
32         return (-1);
33     }
34
35     /* If directory, read the directory */
36     if (S_ISDIR(statbuf.st_mode)) {
37         return (read_proc_dir(file_name, pid, position));
38     }
39
40     return (0);
41 }
42
43 int read_proc_dir(const char *dir_name, const char *pid, int position)
44 {
45     DIR *dp;
46     struct dirent *entry;
47
48     if ((dir_name == NULL) || (strlen(dir_name) > PATH_MAX)) {
49         merror("%s: Invalid directory given", ARGV0);
50         return (-1);
51     }
52
53     /* Open the directory */
54     dp = opendir(dir_name);
55     if (!dp) {
56         return (0);
57     }
58
59     while ((entry = readdir(dp)) != NULL) {
60         char f_name[PATH_MAX + 2];
61
62         /* Ignore . and ..  */
63         if (strcmp(entry->d_name, ".")  == 0 ||
64                 strcmp(entry->d_name, "..") == 0) {
65             continue;
66         }
67
68         if (position == PROC) {
69             char *tmp_str;
70
71             tmp_str = entry->d_name;
72             while (*tmp_str != '\0') {
73                 if (!isdigit((int)*tmp_str)) {
74                     break;
75                 }
76                 tmp_str++;
77             }
78
79             if (*tmp_str != '\0') {
80                 continue;
81             }
82
83             snprintf(f_name, PATH_MAX + 1, "%s/%s", dir_name, entry->d_name);
84             read_proc_file(f_name, pid, position + 1);
85         } else if (position == PID) {
86             if (strcmp(entry->d_name, "task") == 0) {
87                 snprintf(f_name, PATH_MAX + 1, "%s/%s", dir_name, entry->d_name);
88                 read_proc_file(f_name, pid, position + 1);
89             }
90         } else if (position == TASK) {
91             /* Check under proc/pid/task/lwp */
92             if (strcmp(entry->d_name, pid) == 0) {
93                 proc_pid_found = 1;
94                 break;
95             }
96         } else {
97             break;
98         }
99     }
100
101     closedir(dp);
102
103     return (0);
104 }
105
106 /*  Read the /proc directory (if present) and check if it can find
107  *  the given pid (as a pid or as a thread)
108  */
109 int check_rc_readproc(int pid)
110 {
111     char char_pid[32];
112
113     proc_pid_found = 0;
114
115     /* NL threads */
116     snprintf(char_pid, 31, "/proc/.%d", pid);
117     if (is_file(char_pid)) {
118         return (1);
119     }
120
121     snprintf(char_pid, 31, "%d", pid);
122     read_proc_dir("/proc", char_pid, PROC);
123
124     return (proc_pid_found);
125 }
126
127 #endif
128