Imported Upstream version 2.4.3
[platform/upstream/audit.git] / src / ausearch-match.c
1 /*
2 * ausearch-match.c - Extract interesting fields and check for match
3 * Copyright (c) 2005-08, 2011 Red Hat Inc., Durham, North Carolina.
4 * Copyright (c) 2011 IBM Corp.
5 * All Rights Reserved. 
6 *
7 * This software may be freely redistributed and/or modified under the
8 * terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * Authors:
22 *   Steve Grubb <sgrubb@redhat.com>
23 *   Marcelo Henrique Cerri <mhcerri@br.ibm.com>
24 */
25
26 #include "config.h"
27 #include <string.h>
28 #include "libaudit.h"
29 #include "ausearch-options.h"
30 #include "ausearch-parse.h"
31
32 static int strmatch(const char *needle, const char *haystack);
33 static int user_match(llist *l);
34 static int group_match(llist *l);
35 static int context_match(llist *l);
36
37 /*
38  * This function performs that matching of search params with the record.
39  * It returns 1 on a match, and 0 if no match. The way that this function
40  * works is that it will try to determine if there is not a match and exit
41  * as soon as possible. We can do this since all command line params form
42  * an 'and' statement. If anything does not match, no need to evaluate the
43  * rest of the params.
44  */
45 #include <stdio.h>
46 int match(llist *l)
47 {
48         // Are we within time range?
49         if (start_time == 0 || l->e.sec >= start_time) {
50                 if (end_time == 0 || l->e.sec <= end_time) {
51                         if (event_id == -1 || event_id == l->e.serial) {
52                                 // OK - do the heavier checking
53                                 if (extract_search_items(l)) {
54                                         return 0;
55                                 }
56
57                                 // perform additional tests for the field
58                                 if (event_node_list) {
59                                         const snode *sn;
60                                         int found=0;
61                                         slist *sptr = event_node_list;
62
63                                         if (l->e.node == NULL)
64                                                 return 0;
65
66                                         slist_first(sptr);
67                                         sn=slist_get_cur(sptr);
68                                         while (sn && !found) {
69                                                 if (sn->str &&  (!strcmp(sn->str, l->e.node)))
70                                                         found++;
71                                                 else
72                                                         sn=slist_next(sptr);
73                                         }
74                                         if (!found)
75                                                 return 0;
76                                 }
77                                 if (user_match(l) == 0)
78                                         return 0;
79                                 if (group_match(l) == 0)
80                                         return 0;
81                                 if ((event_ppid != -1) && 
82                                                 (event_ppid != l->s.ppid))
83                                         return 0;
84                                 if ((event_pid != -1) && 
85                                                 (event_pid != l->s.pid))
86                                         return 0;
87                                 if (event_machine != -1 && 
88                                                 (event_machine !=
89                                         audit_elf_to_machine(l->s.arch)))
90                                         return 0;
91                                 if ((event_syscall != -1) && 
92                                         (event_syscall != l->s.syscall))
93                                                 return 0;
94                                 if ((event_session_id != -2) &&
95                                         (event_session_id != l->s.session_id))
96                                         return 0;
97                                 if (event_exit_is_set) {
98                                         if (l->s.exit_is_set == 0)
99                                                 return 0;
100                                         if (event_exit != l->s.exit)
101                                                 return 0;
102                                 }
103
104                                 if ((event_success != S_UNSET) &&
105                                                 (event_success != l->s.success))
106                                         return 0;
107                                 // event_type requires looking at each item
108                                 if (event_type != NULL) {
109                                         int found = 0;
110                                         const lnode *n;
111
112                                         list_first(l);
113                                         n = list_get_cur(l);
114                                         do {
115                                                 int_node *in;
116                                                 ilist_first(event_type);
117                                                 in = ilist_get_cur(event_type);
118                                                 do {
119                                                         if (in->num == n->type){
120                                                                 found = 1;
121                                                                 break;
122                                                         }
123                                                 } while((in = 
124                                                     ilist_next(event_type)));
125                                                 if (found)
126                                                         break;
127                                         } while ((n = list_next(l)));
128                                         if (!found)
129                                                 return 0;
130                                 }
131
132                                 // Done all the easy compares, now do the 
133                                 // string searches.
134                                 if (event_filename) {
135                                         int found = 0;
136                                         if (l->s.filename == NULL && l->s.cwd == NULL)
137                                                 return 0;
138                                         if (l->s.filename) {
139                                                 const snode *sn;
140                                                 slist *sptr = l->s.filename;
141
142                                                 slist_first(sptr);
143                                                 sn=slist_get_cur(sptr);
144                                                 do {
145                                                         if (sn->str == NULL)
146                                                                 return 0;
147                                                         if (strmatch(
148                                                                 event_filename,
149                                                                 sn->str)) {
150                                                                 found = 1;
151                                                                 break;
152                                                         }
153                                                 } while ((sn=slist_next(sptr)));
154
155                                                 if (!found && l->s.cwd == NULL)
156                                                         return 0;
157                                         }
158                                         if (l->s.cwd && !found) {
159                                                 /* Check cwd, too */
160                                                 if (strmatch(event_filename,
161                                                                 l->s.cwd) == 0)
162                                                         return 0;
163                                         }
164                                 }
165                                 if (event_hostname) {
166                                         if (l->s.hostname == NULL)
167                                                 return 0;
168                                         if (strmatch(event_hostname, 
169                                                 l->s.hostname) == 0)
170                                                 return 0; 
171                                 }
172                                 if (event_terminal) {
173                                         if (l->s.terminal == NULL)
174                                                 return 0;
175                                         if (strmatch(event_terminal, 
176                                                 l->s.terminal) == 0)
177                                                 return 0; 
178                                 }
179                                 if (event_exe) {
180                                         if (l->s.exe == NULL)
181                                                 return 0;
182                                         if (strmatch(event_exe, 
183                                                 l->s.exe) == 0)
184                                                 return 0; 
185                                 }                               
186                                 if (event_comm) {
187                                         if (l->s.comm == NULL)
188                                                 return 0;
189                                         if (strmatch(event_comm, 
190                                                 l->s.comm) == 0)
191                                                 return 0; 
192                                 }                               
193                                 if (event_key) {
194                                         if (l->s.key == NULL)
195                                                 return 0;
196                                         else {
197                                                 int found = 0;
198                                                 const snode *sn;
199                                                 slist *sptr = l->s.key;
200
201                                                 slist_first(sptr);
202                                                 sn=slist_get_cur(sptr);
203                                                 do {
204                                                         if (sn->str == NULL)
205                                                                 return 0;
206                                                         if (strmatch(
207                                                                 event_key,
208                                                                 sn->str)) {
209                                                                 found = 1;
210                                                                 break;
211                                                         }
212                                                 } while ((sn=slist_next(sptr)));
213                                                 if (!found)
214                                                         return 0;
215                                         }
216                                 }                               
217                                 if (event_vmname) {
218                                         if (l->s.vmname == NULL)
219                                                 return 0;
220                                         if (strmatch(event_vmname,
221                                                         l->s.vmname) == 0)
222                                                 return 0;
223                                 }
224                                 if (event_uuid) {
225                                         if (l->s.uuid == NULL)
226                                                 return 0;
227                                         if (strmatch(event_uuid,
228                                                         l->s.uuid) == 0)
229                                                 return 0;
230                                 }
231                                 if (context_match(l) == 0)
232                                         return 0;
233                                 return 1;
234                         }
235                 }
236         }
237         return 0;
238 }
239
240 /*
241  * This function compares strings. It returns a 0 if no match and a 1 if
242  * there is a match 
243  */
244 static int strmatch(const char *needle, const char *haystack)
245 {
246         if (event_exact_match) {
247                 if (strcmp(haystack, needle) != 0)
248                         return 0; 
249         } else {
250                 if (strstr(haystack, needle) == NULL)
251                         return 0; 
252         }
253         return 1;
254 }
255
256 /*
257  * This function compares user id's. It returns a 0 if no match and a 1 if
258  * there is a match 
259  */
260 static int user_match(llist *l)
261 {
262         if (event_ua) {
263                 // This will "or" the user tests
264                 if (event_uid == l->s.uid)
265                         return 1;
266                 if (event_euid == l->s.euid)
267                         return 1;
268                 if (event_loginuid == l->s.loginuid)
269                         return 1;
270                 return 0;
271         } else {
272                 // This will "and" the user tests
273                 if ((event_uid != -1) && (event_uid != l->s.uid))
274                         return 0;
275                 if ((event_euid != -1) &&(event_euid != l->s.euid))
276                         return 0;
277                 if ((event_loginuid != -2) &&
278                                 (event_loginuid != l->s.loginuid))
279                         return 0;
280         }
281         return 1;
282 }
283
284 /*
285  * This function compares group id's. It returns a 0 if no match and a 1 if
286  * there is a match 
287  */
288 static int group_match(llist *l)
289 {
290         if (event_ga) {
291                 // This will "or" the group tests
292                 if (event_gid == l->s.gid)
293                         return 1;
294                 if (event_egid == l->s.egid)
295                         return 1;
296                 return 0;
297         } else {
298                 // This will "and" the group tests
299                 if ((event_gid != -1) && (event_gid != l->s.gid))
300                         return 0;
301                 if ((event_egid != -1) &&(event_egid != l->s.egid))
302                         return 0;
303         }
304         return 1;
305 }
306
307 /*
308  * This function compares contexts. It returns a 0 if no match and a 1 if
309  * there is a match 
310  */
311 static int context_match(llist *l)
312 {
313         if (event_se) { /* This does the "or" check if -se test */
314                 if (event_subject) {
315                         if (l->s.avc && alist_find_subj(l->s.avc)) {
316                                 do {
317                                         if (strmatch(event_subject, 
318                                                 l->s.avc->cur->scontext))
319                                                 return 1;
320                                 } while(alist_next_subj(l->s.avc));
321                         }
322                 } 
323                 if (event_object) {
324                         if (l->s.avc) {
325                                 alist_first(l->s.avc);
326                                 if (alist_find_obj(l->s.avc)) {
327                                         do {
328                                                 if (strmatch(event_object, 
329                                                     l->s.avc->cur->tcontext))
330                                                     return 1;
331                                         } while(alist_next_obj(l->s.avc));
332                                 }
333                         }
334                 }
335                 return 0;
336         } else {
337                 if (event_subject) {
338                         if (l->s.avc == NULL)
339                                 return 0;
340                         if (alist_find_subj(l->s.avc)) {
341                                 do {
342                                         if (strmatch(event_subject, 
343                                                 l->s.avc->cur->scontext))
344                                                 return 1;
345                                 } while(alist_next_subj(l->s.avc));
346                         }
347                         return 0;
348                 } 
349                 if (event_object) {
350                         if (l->s.avc == NULL)
351                                 return 0;
352                         if (alist_find_obj(l->s.avc)) {
353                                 do {
354                                         if (strmatch(event_object, 
355                                                 l->s.avc->cur->tcontext))
356                                                 return 1;
357                                 } while(alist_next_obj(l->s.avc));
358                         }
359                         return 0;
360                 }
361         }
362         return 1;
363 }
364