]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/audit/file-attribute-modify.c
MFC many audit(4) tests.
[FreeBSD/FreeBSD.git] / tests / sys / audit / file-attribute-modify.c
1 /*-
2  * Copyright (c) 2018 Aniket Pandey
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * SUCH DAMAGE.
24  *
25  * $FreeBSD$
26  */
27
28 #include <sys/file.h>
29 #include <sys/stat.h>
30
31 #include <atf-c.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34
35 #include "utils.h"
36
37 static pid_t pid;
38 static uid_t uid = -1;
39 static gid_t gid = -1;
40 static int filedesc;
41 static struct pollfd fds[1];
42 static mode_t mode = 0777;
43 static char extregex[80];
44 static const char *auclass = "fm";
45 static const char *path = "fileforaudit";
46 static const char *errpath = "adirhasnoname/fileforaudit";
47 static const char *successreg = "fileforaudit.*return,success";
48 static const char *failurereg = "fileforaudit.*return,failure";
49
50
51 ATF_TC_WITH_CLEANUP(flock_success);
52 ATF_TC_HEAD(flock_success, tc)
53 {
54         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
55                                         "flock(2) call");
56 }
57
58 ATF_TC_BODY(flock_success, tc)
59 {
60         pid = getpid();
61         snprintf(extregex, sizeof(extregex), "flock.*%d.*return,success", pid);
62
63         /* File needs to exist to call flock(2) */
64         ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
65         FILE *pipefd = setup(fds, auclass);
66         ATF_REQUIRE_EQ(0, flock(filedesc, LOCK_SH));
67         check_audit(fds, extregex, pipefd);
68         close(filedesc);
69 }
70
71 ATF_TC_CLEANUP(flock_success, tc)
72 {
73         cleanup();
74 }
75
76
77 ATF_TC_WITH_CLEANUP(flock_failure);
78 ATF_TC_HEAD(flock_failure, tc)
79 {
80         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
81                                         "flock(2) call");
82 }
83
84 ATF_TC_BODY(flock_failure, tc)
85 {
86         const char *regex = "flock.*return,failure : Bad file descriptor";
87         FILE *pipefd = setup(fds, auclass);
88         ATF_REQUIRE_EQ(-1, flock(-1, LOCK_SH));
89         check_audit(fds, regex, pipefd);
90 }
91
92 ATF_TC_CLEANUP(flock_failure, tc)
93 {
94         cleanup();
95 }
96
97
98 ATF_TC_WITH_CLEANUP(fcntl_success);
99 ATF_TC_HEAD(fcntl_success, tc)
100 {
101         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
102                                         "fcntl(2) call");
103 }
104
105 ATF_TC_BODY(fcntl_success, tc)
106 {
107         int flagstatus;
108         /* File needs to exist to call fcntl(2) */
109         ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
110         FILE *pipefd = setup(fds, auclass);
111
112         /* Retrieve the status flags of 'filedesc' and store it in flagstatus */
113         ATF_REQUIRE((flagstatus = fcntl(filedesc, F_GETFL, 0)) != -1);
114         snprintf(extregex, sizeof(extregex),
115                         "fcntl.*return,success,%d", flagstatus);
116         check_audit(fds, extregex, pipefd);
117         close(filedesc);
118 }
119
120 ATF_TC_CLEANUP(fcntl_success, tc)
121 {
122         cleanup();
123 }
124
125
126 ATF_TC_WITH_CLEANUP(fcntl_failure);
127 ATF_TC_HEAD(fcntl_failure, tc)
128 {
129         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
130                                         "fcntl(2) call");
131 }
132
133 ATF_TC_BODY(fcntl_failure, tc)
134 {
135         const char *regex = "fcntl.*return,failure : Bad file descriptor";
136         FILE *pipefd = setup(fds, auclass);
137         ATF_REQUIRE_EQ(-1, fcntl(-1, F_GETFL, 0));
138         check_audit(fds, regex, pipefd);
139 }
140
141 ATF_TC_CLEANUP(fcntl_failure, tc)
142 {
143         cleanup();
144 }
145
146
147 ATF_TC_WITH_CLEANUP(fsync_success);
148 ATF_TC_HEAD(fsync_success, tc)
149 {
150         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
151                                         "fsync(2) call");
152 }
153
154 ATF_TC_BODY(fsync_success, tc)
155 {
156         pid = getpid();
157         snprintf(extregex, sizeof(extregex), "fsync.*%d.*return,success", pid);
158
159         /* File needs to exist to call fsync(2) */
160         ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
161         FILE *pipefd = setup(fds, auclass);
162         ATF_REQUIRE_EQ(0, fsync(filedesc));
163         check_audit(fds, extregex, pipefd);
164         close(filedesc);
165 }
166
167 ATF_TC_CLEANUP(fsync_success, tc)
168 {
169         cleanup();
170 }
171
172
173 ATF_TC_WITH_CLEANUP(fsync_failure);
174 ATF_TC_HEAD(fsync_failure, tc)
175 {
176         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
177                                         "fsync(2) call");
178 }
179
180 ATF_TC_BODY(fsync_failure, tc)
181 {
182         const char *regex = "fsync.*return,failure : Bad file descriptor";
183         FILE *pipefd = setup(fds, auclass);
184         /* Failure reason: Invalid file descriptor */
185         ATF_REQUIRE_EQ(-1, fsync(-1));
186         check_audit(fds, regex, pipefd);
187 }
188
189 ATF_TC_CLEANUP(fsync_failure, tc)
190 {
191         cleanup();
192 }
193
194
195 ATF_TC_WITH_CLEANUP(chmod_success);
196 ATF_TC_HEAD(chmod_success, tc)
197 {
198         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
199                                         "chmod(2) call");
200 }
201
202 ATF_TC_BODY(chmod_success, tc)
203 {
204         /* File needs to exist to call chmod(2) */
205         ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
206         FILE *pipefd = setup(fds, auclass);
207         ATF_REQUIRE_EQ(0, chmod(path, mode));
208         check_audit(fds, successreg, pipefd);
209         close(filedesc);
210 }
211
212 ATF_TC_CLEANUP(chmod_success, tc)
213 {
214         cleanup();
215 }
216
217
218 ATF_TC_WITH_CLEANUP(chmod_failure);
219 ATF_TC_HEAD(chmod_failure, tc)
220 {
221         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
222                                         "chmod(2) call");
223 }
224
225 ATF_TC_BODY(chmod_failure, tc)
226 {
227         FILE *pipefd = setup(fds, auclass);
228         /* Failure reason: file does not exist */
229         ATF_REQUIRE_EQ(-1, chmod(errpath, mode));
230         check_audit(fds, failurereg, pipefd);
231 }
232
233 ATF_TC_CLEANUP(chmod_failure, tc)
234 {
235         cleanup();
236 }
237
238
239 ATF_TC_WITH_CLEANUP(fchmod_success);
240 ATF_TC_HEAD(fchmod_success, tc)
241 {
242         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
243                                         "fchmod(2) call");
244 }
245
246 ATF_TC_BODY(fchmod_success, tc)
247 {
248         pid = getpid();
249         snprintf(extregex, sizeof(extregex), "fchmod.*%d.*return,success", pid);
250
251         /* File needs to exist to call fchmod(2) */
252         ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
253         FILE *pipefd = setup(fds, auclass);
254         ATF_REQUIRE_EQ(0, fchmod(filedesc, mode));
255         check_audit(fds, extregex, pipefd);
256         close(filedesc);
257 }
258
259 ATF_TC_CLEANUP(fchmod_success, tc)
260 {
261         cleanup();
262 }
263
264
265 ATF_TC_WITH_CLEANUP(fchmod_failure);
266 ATF_TC_HEAD(fchmod_failure, tc)
267 {
268         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
269                                         "fchmod(2) call");
270 }
271
272 ATF_TC_BODY(fchmod_failure, tc)
273 {
274         const char *regex = "fchmod.*return,failure : Bad file descriptor";
275         FILE *pipefd = setup(fds, auclass);
276         /* Failure reason: Invalid file descriptor */
277         ATF_REQUIRE_EQ(-1, fchmod(-1, mode));
278         check_audit(fds, regex, pipefd);
279 }
280
281 ATF_TC_CLEANUP(fchmod_failure, tc)
282 {
283         cleanup();
284 }
285
286
287 ATF_TC_WITH_CLEANUP(lchmod_success);
288 ATF_TC_HEAD(lchmod_success, tc)
289 {
290         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
291                                         "lchmod(2) call");
292 }
293
294 ATF_TC_BODY(lchmod_success, tc)
295 {
296         /* Symbolic link needs to exist to call lchmod(2) */
297         ATF_REQUIRE_EQ(0, symlink("symlink", path));
298         FILE *pipefd = setup(fds, auclass);
299         ATF_REQUIRE_EQ(0, lchmod(path, mode));
300         check_audit(fds, successreg, pipefd);
301 }
302
303 ATF_TC_CLEANUP(lchmod_success, tc)
304 {
305         cleanup();
306 }
307
308
309 ATF_TC_WITH_CLEANUP(lchmod_failure);
310 ATF_TC_HEAD(lchmod_failure, tc)
311 {
312         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
313                                         "lchmod(2) call");
314 }
315
316 ATF_TC_BODY(lchmod_failure, tc)
317 {
318         FILE *pipefd = setup(fds, auclass);
319         /* Failure reason: file does not exist */
320         ATF_REQUIRE_EQ(-1, lchmod(errpath, mode));
321         check_audit(fds, failurereg, pipefd);
322 }
323
324 ATF_TC_CLEANUP(lchmod_failure, tc)
325 {
326         cleanup();
327 }
328
329
330 ATF_TC_WITH_CLEANUP(fchmodat_success);
331 ATF_TC_HEAD(fchmodat_success, tc)
332 {
333         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
334                                         "fchmodat(2) call");
335 }
336
337 ATF_TC_BODY(fchmodat_success, tc)
338 {
339         /* File needs to exist to call fchmodat(2) */
340         ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
341         FILE *pipefd = setup(fds, auclass);
342         ATF_REQUIRE_EQ(0, fchmodat(AT_FDCWD, path, mode, 0));
343         check_audit(fds, successreg, pipefd);
344         close(filedesc);
345 }
346
347 ATF_TC_CLEANUP(fchmodat_success, tc)
348 {
349         cleanup();
350 }
351
352
353 ATF_TC_WITH_CLEANUP(fchmodat_failure);
354 ATF_TC_HEAD(fchmodat_failure, tc)
355 {
356         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
357                                         "fchmodat(2) call");
358 }
359
360 ATF_TC_BODY(fchmodat_failure, tc)
361 {
362         FILE *pipefd = setup(fds, auclass);
363         /* Failure reason: file does not exist */
364         ATF_REQUIRE_EQ(-1, fchmodat(AT_FDCWD, errpath, mode, 0));
365         check_audit(fds, failurereg, pipefd);
366 }
367
368 ATF_TC_CLEANUP(fchmodat_failure, tc)
369 {
370         cleanup();
371 }
372
373
374 ATF_TC_WITH_CLEANUP(chown_success);
375 ATF_TC_HEAD(chown_success, tc)
376 {
377         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
378                                         "chown(2) call");
379 }
380
381 ATF_TC_BODY(chown_success, tc)
382 {
383         /* File needs to exist to call chown(2) */
384         ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
385         FILE *pipefd = setup(fds, auclass);
386         ATF_REQUIRE_EQ(0, chown(path, uid, gid));
387         check_audit(fds, successreg, pipefd);
388         close(filedesc);
389 }
390
391 ATF_TC_CLEANUP(chown_success, tc)
392 {
393         cleanup();
394 }
395
396
397 ATF_TC_WITH_CLEANUP(chown_failure);
398 ATF_TC_HEAD(chown_failure, tc)
399 {
400         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
401                                         "chown(2) call");
402 }
403
404 ATF_TC_BODY(chown_failure, tc)
405 {
406         FILE *pipefd = setup(fds, auclass);
407         /* Failure reason: file does not exist */
408         ATF_REQUIRE_EQ(-1, chown(errpath, uid, gid));
409         check_audit(fds, failurereg, pipefd);
410 }
411
412 ATF_TC_CLEANUP(chown_failure, tc)
413 {
414         cleanup();
415 }
416
417
418 ATF_TC_WITH_CLEANUP(fchown_success);
419 ATF_TC_HEAD(fchown_success, tc)
420 {
421         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
422                                         "fchown(2) call");
423 }
424
425 ATF_TC_BODY(fchown_success, tc)
426 {
427         pid = getpid();
428         snprintf(extregex, sizeof(extregex), "fchown.*%d.*return,success", pid);
429
430         /* File needs to exist to call fchown(2) */
431         ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
432         FILE *pipefd = setup(fds, auclass);
433         ATF_REQUIRE_EQ(0, fchown(filedesc, uid, gid));
434         check_audit(fds, extregex, pipefd);
435         close(filedesc);
436 }
437
438 ATF_TC_CLEANUP(fchown_success, tc)
439 {
440         cleanup();
441 }
442
443
444 ATF_TC_WITH_CLEANUP(fchown_failure);
445 ATF_TC_HEAD(fchown_failure, tc)
446 {
447         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
448                                         "fchown(2) call");
449 }
450
451 ATF_TC_BODY(fchown_failure, tc)
452 {
453         const char *regex = "fchown.*return,failure : Bad file descriptor";
454         FILE *pipefd = setup(fds, auclass);
455         /* Failure reason: Invalid file descriptor */
456         ATF_REQUIRE_EQ(-1, fchown(-1, uid, gid));
457         check_audit(fds, regex, pipefd);
458 }
459
460 ATF_TC_CLEANUP(fchown_failure, tc)
461 {
462         cleanup();
463 }
464
465
466 ATF_TC_WITH_CLEANUP(lchown_success);
467 ATF_TC_HEAD(lchown_success, tc)
468 {
469         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
470                                         "lchown(2) call");
471 }
472
473 ATF_TC_BODY(lchown_success, tc)
474 {
475         /* Symbolic link needs to exist to call lchown(2) */
476         ATF_REQUIRE_EQ(0, symlink("symlink", path));
477         FILE *pipefd = setup(fds, auclass);
478         ATF_REQUIRE_EQ(0, lchown(path, uid, gid));
479         check_audit(fds, successreg, pipefd);
480 }
481
482 ATF_TC_CLEANUP(lchown_success, tc)
483 {
484         cleanup();
485 }
486
487
488 ATF_TC_WITH_CLEANUP(lchown_failure);
489 ATF_TC_HEAD(lchown_failure, tc)
490 {
491         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
492                                         "lchown(2) call");
493 }
494
495 ATF_TC_BODY(lchown_failure, tc)
496 {
497         FILE *pipefd = setup(fds, auclass);
498         /* Failure reason: Symbolic link does not exist */
499         ATF_REQUIRE_EQ(-1, lchown(errpath, uid, gid));
500         check_audit(fds, failurereg, pipefd);
501 }
502
503 ATF_TC_CLEANUP(lchown_failure, tc)
504 {
505         cleanup();
506 }
507
508
509 ATF_TC_WITH_CLEANUP(fchownat_success);
510 ATF_TC_HEAD(fchownat_success, tc)
511 {
512         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
513                                         "fchownat(2) call");
514 }
515
516 ATF_TC_BODY(fchownat_success, tc)
517 {
518         /* File needs to exist to call fchownat(2) */
519         ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1);
520         FILE *pipefd = setup(fds, auclass);
521         ATF_REQUIRE_EQ(0, fchownat(AT_FDCWD, path, uid, gid, 0));
522         check_audit(fds, successreg, pipefd);
523         close(filedesc);
524 }
525
526 ATF_TC_CLEANUP(fchownat_success, tc)
527 {
528         cleanup();
529 }
530
531
532 ATF_TC_WITH_CLEANUP(fchownat_failure);
533 ATF_TC_HEAD(fchownat_failure, tc)
534 {
535         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
536                                         "fchownat(2) call");
537 }
538
539 ATF_TC_BODY(fchownat_failure, tc)
540 {
541         FILE *pipefd = setup(fds, auclass);
542         /* Failure reason: file does not exist */
543         ATF_REQUIRE_EQ(-1, fchownat(AT_FDCWD, errpath, uid, gid, 0));
544         check_audit(fds, failurereg, pipefd);
545 }
546
547 ATF_TC_CLEANUP(fchownat_failure, tc)
548 {
549         cleanup();
550 }
551
552
553 ATF_TP_ADD_TCS(tp)
554 {
555         ATF_TP_ADD_TC(tp, flock_success);
556         ATF_TP_ADD_TC(tp, flock_failure);
557         ATF_TP_ADD_TC(tp, fcntl_success);
558         ATF_TP_ADD_TC(tp, fcntl_failure);
559         ATF_TP_ADD_TC(tp, fsync_success);
560         ATF_TP_ADD_TC(tp, fsync_failure);
561
562         ATF_TP_ADD_TC(tp, chmod_success);
563         ATF_TP_ADD_TC(tp, chmod_failure);
564         ATF_TP_ADD_TC(tp, fchmod_success);
565         ATF_TP_ADD_TC(tp, fchmod_failure);
566         ATF_TP_ADD_TC(tp, lchmod_success);
567         ATF_TP_ADD_TC(tp, lchmod_failure);
568         ATF_TP_ADD_TC(tp, fchmodat_success);
569         ATF_TP_ADD_TC(tp, fchmodat_failure);
570
571         ATF_TP_ADD_TC(tp, chown_success);
572         ATF_TP_ADD_TC(tp, chown_failure);
573         ATF_TP_ADD_TC(tp, fchown_success);
574         ATF_TP_ADD_TC(tp, fchown_failure);
575         ATF_TP_ADD_TC(tp, lchown_success);
576         ATF_TP_ADD_TC(tp, lchown_failure);
577         ATF_TP_ADD_TC(tp, fchownat_success);
578         ATF_TP_ADD_TC(tp, fchownat_failure);
579
580         return (atf_no_error());
581 }