26875c98944445151249923c75b62373c5db8e43
[samba.git] / lib / audit_logging / tests / audit_logging_test.c
1 /*
2  * Unit tests for the audit_logging library.
3  *
4  *  Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 /*
22  * from cmocka.c:
23  * These headers or their equivalents should be included prior to
24  * including
25  * this header file.
26  *
27  * #include <stdarg.h>
28  * #include <stddef.h>
29  * #include <setjmp.h>
30  *
31  * This allows test applications to use custom definitions of C standard
32  * library functions and types.
33  *
34  */
35
36 /*
37  * Note that the messaging routines (audit_message_send and get_event_server)
38  * are not tested by these unit tests.  Currently they are for integration
39  * test support, and as such are exercised by the integration tests.
40  */
41 #include <stdarg.h>
42 #include <stddef.h>
43 #include <setjmp.h>
44 #include <cmocka.h>
45
46 #include <string.h>
47 #include <time.h>
48 #include <tevent.h>
49 #include <config.h>
50 #include <talloc.h>
51 #include "lib/util/talloc_stack.h"
52
53 #include "lib/util/data_blob.h"
54 #include "lib/util/time.h"
55 #include "libcli/util/werror.h"
56 #include "lib/param/loadparm.h"
57 #include "libcli/security/dom_sid.h"
58 #include "librpc/ndr/libndr.h"
59
60 #include "lib/audit_logging/audit_logging.h"
61
62 static void test_json_add_int(void **state)
63 {
64         struct json_object object;
65         struct json_t *value = NULL;
66         double n;
67
68         object = json_new_object();
69         json_add_int(&object, "positive_one", 1);
70         json_add_int(&object, "zero", 0);
71         json_add_int(&object, "negative_one", -1);
72
73
74         assert_int_equal(3, json_object_size(object.root));
75
76         value = json_object_get(object.root, "positive_one");
77         assert_true(json_is_integer(value));
78         n = json_number_value(value);
79         assert_true(n == 1.0);
80
81         value = json_object_get(object.root, "zero");
82         assert_true(json_is_integer(value));
83         n = json_number_value(value);
84         assert_true(n == 0.0);
85
86         value = json_object_get(object.root, "negative_one");
87         assert_true(json_is_integer(value));
88         n = json_number_value(value);
89         assert_true(n == -1.0);
90
91         json_free(&object);
92 }
93
94 static void test_json_add_bool(void **state)
95 {
96         struct json_object object;
97         struct json_t *value = NULL;
98
99         object = json_new_object();
100         json_add_bool(&object, "true", true);
101         json_add_bool(&object, "false", false);
102
103
104         assert_int_equal(2, json_object_size(object.root));
105
106         value = json_object_get(object.root, "true");
107         assert_true(json_is_boolean(value));
108         assert_true(value == json_true());
109
110         value = json_object_get(object.root, "false");
111         assert_true(json_is_boolean(value));
112         assert_true(value == json_false());
113
114         json_free(&object);
115 }
116
117 static void test_json_add_string(void **state)
118 {
119         struct json_object object;
120         struct json_t *value = NULL;
121         const char *s = NULL;
122
123         object = json_new_object();
124         json_add_string(&object, "null", NULL);
125         json_add_string(&object, "empty", "");
126         json_add_string(&object, "name", "value");
127
128
129
130         assert_int_equal(3, json_object_size(object.root));
131
132         value = json_object_get(object.root, "null");
133         assert_true(json_is_null(value));
134
135         value = json_object_get(object.root, "empty");
136         assert_true(json_is_string(value));
137         s = json_string_value(value);
138         assert_string_equal("", s);
139
140         value = json_object_get(object.root, "name");
141         assert_true(json_is_string(value));
142         s = json_string_value(value);
143         assert_string_equal("value", s);
144         json_free(&object);
145 }
146
147 static void test_json_add_object(void **state)
148 {
149         struct json_object object;
150         struct json_object other;
151         struct json_t *value = NULL;
152
153         object = json_new_object();
154         other  = json_new_object();
155         json_add_object(&object, "null", NULL);
156         json_add_object(&object, "other", &other);
157
158
159
160         assert_int_equal(2, json_object_size(object.root));
161
162         value = json_object_get(object.root, "null");
163         assert_true(json_is_null(value));
164
165         value = json_object_get(object.root, "other");
166         assert_true(json_is_object(value));
167         assert_ptr_equal(other.root, value);
168
169         json_free(&object);
170 }
171
172 static void test_json_add_to_array(void **state)
173 {
174         struct json_object array;
175         struct json_object o1;
176         struct json_object o2;
177         struct json_object o3;
178         struct json_t *value = NULL;
179
180         array = json_new_array();
181         assert_true(json_is_array(array.root));
182
183         o1 = json_new_object();
184         o2 = json_new_object();
185         o3 = json_new_object();
186
187         json_add_object(&array, NULL, &o3);
188         json_add_object(&array, "", &o2);
189         json_add_object(&array, "will-be-ignored", &o1);
190         json_add_object(&array, NULL, NULL);
191
192         assert_int_equal(4, json_array_size(array.root));
193
194         value = json_array_get(array.root, 0);
195         assert_ptr_equal(o3.root, value);
196
197         value = json_array_get(array.root, 1);
198         assert_ptr_equal(o2.root, value);
199
200         value = json_array_get(array.root, 2);
201         assert_ptr_equal(o1.root, value);
202
203         value = json_array_get(array.root, 3);
204         assert_true(json_is_null(value));
205
206         json_free(&array);
207
208 }
209
210 static void test_json_add_timestamp(void **state)
211 {
212         struct json_object object;
213         struct json_t *ts = NULL;
214         const char *t = NULL;
215         int rc;
216         int usec, tz;
217         char c[2];
218         struct tm tm;
219         time_t before;
220         time_t after;
221         time_t actual;
222         const int adjustment = 1;
223
224
225         object = json_new_object();
226         before = time(NULL);
227         json_add_timestamp(&object);
228         after = time(NULL);
229
230         ts = json_object_get(object.root, "timestamp");
231         assert_true(json_is_string(ts));
232
233         /*
234          * Convert the returned ISO 8601 timestamp into a time_t
235          * Note for convenience we ignore the value of the microsecond
236          * part of the time stamp.
237          */
238         t = json_string_value(ts);
239         rc = sscanf(
240                 t,
241                 "%4d-%2d-%2dT%2d:%2d:%2d.%6d%1c%4d",
242                 &tm.tm_year,
243                 &tm.tm_mon,
244                 &tm.tm_mday,
245                 &tm.tm_hour,
246                 &tm.tm_min,
247                 &tm.tm_sec,
248                 &usec,
249                 c,
250                 &tz);
251         assert_int_equal(9, rc);
252         tm.tm_year = tm.tm_year - 1900;
253         tm.tm_mon = tm.tm_mon - 1;
254         tm.tm_isdst = -1;
255         actual = mktime(&tm);
256
257         /*
258          * The timestamp should be before <= actual <= after
259          * but we adjust the times to cater for any precision issues.
260          */
261         before -= adjustment;
262         after += adjustment;
263         assert_true(difftime(actual, before) >= 0);
264         assert_true(difftime(after, actual) >= 0);
265
266         json_free(&object);
267 }
268
269 static void test_json_add_stringn(void **state)
270 {
271         struct json_object object;
272         struct json_t *value = NULL;
273         const char *s = NULL;
274
275         object = json_new_object();
276         json_add_stringn(&object, "null", NULL, 10);
277         json_add_stringn(&object, "null-zero-len", NULL, 0);
278         json_add_stringn(&object, "empty", "", 1);
279         json_add_stringn(&object, "empty-zero-len", "", 0);
280         json_add_stringn(&object, "value-less-than-len", "123456", 7);
281         json_add_stringn(&object, "value-greater-than-len", "abcd", 3);
282         json_add_stringn(&object, "value-equal-len", "ZYX", 3);
283         json_add_stringn(&object, "value-len-is-zero", "this will be null", 0);
284
285
286         assert_int_equal(8, json_object_size(object.root));
287
288         value = json_object_get(object.root, "null");
289         assert_true(json_is_null(value));
290
291         value = json_object_get(object.root, "null-zero-len");
292         assert_true(json_is_null(value));
293
294         value = json_object_get(object.root, "empty");
295         assert_true(json_is_string(value));
296         s = json_string_value(value);
297         assert_string_equal("", s);
298
299         value = json_object_get(object.root, "empty-zero-len");
300         assert_true(json_is_null(value));
301
302         value = json_object_get(object.root, "value-greater-than-len");
303         assert_true(json_is_string(value));
304         s = json_string_value(value);
305         assert_string_equal("abc", s);
306         assert_int_equal(3, strlen(s));
307
308         value = json_object_get(object.root, "value-equal-len");
309         assert_true(json_is_string(value));
310         s = json_string_value(value);
311         assert_string_equal("ZYX", s);
312         assert_int_equal(3, strlen(s));
313
314         value = json_object_get(object.root, "value-len-is-zero");
315         assert_true(json_is_null(value));
316
317         json_free(&object);
318 }
319
320 static void test_json_add_version(void **state)
321 {
322         struct json_object object;
323         struct json_t *version = NULL;
324         struct json_t *v = NULL;
325         double n;
326
327         object = json_new_object();
328         json_add_version(&object, 3, 1);
329
330         assert_int_equal(1, json_object_size(object.root));
331
332         version = json_object_get(object.root, "version");
333         assert_true(json_is_object(version));
334         assert_int_equal(2, json_object_size(version));
335
336         v = json_object_get(version, "major");
337         assert_true(json_is_integer(v));
338         n = json_number_value(v);
339         assert_true(n == 3.0);
340
341         v = json_object_get(version, "minor");
342         assert_true(json_is_integer(v));
343         n = json_number_value(v);
344         assert_true(n == 1.0);
345
346         json_free(&object);
347 }
348
349 static void test_json_add_address(void **state)
350 {
351         struct json_object object;
352         struct json_t *value = NULL;
353         struct tsocket_address *ip4  = NULL;
354         struct tsocket_address *ip6  = NULL;
355         struct tsocket_address *pipe = NULL;
356         const char *s = NULL;
357         int rc;
358
359         TALLOC_CTX *ctx = talloc_new(NULL);
360
361         object = json_new_object();
362
363         json_add_address(&object, "null", NULL);
364
365         rc = tsocket_address_inet_from_strings(
366                 ctx,
367                 "ip",
368                 "127.0.0.1",
369                 21,
370                 &ip4);
371         assert_int_equal(0, rc);
372         json_add_address(&object, "ip4", ip4);
373
374         rc = tsocket_address_inet_from_strings(
375                 ctx,
376                 "ip",
377                 "2001:db8:0:0:1:0:0:1",
378                 42,
379                 &ip6);
380         assert_int_equal(0, rc);
381         json_add_address(&object, "ip6", ip6);
382
383         rc = tsocket_address_unix_from_path(ctx, "/samba/pipe", &pipe);
384         assert_int_equal(0, rc);
385         json_add_address(&object, "pipe", pipe);
386
387         assert_int_equal(4, json_object_size(object.root));
388
389         value = json_object_get(object.root, "null");
390         assert_true(json_is_null(value));
391
392         value = json_object_get(object.root, "ip4");
393         assert_true(json_is_string(value));
394         s = json_string_value(value);
395         assert_string_equal("ipv4:127.0.0.1:21", s);
396
397         value = json_object_get(object.root, "ip6");
398         assert_true(json_is_string(value));
399         s = json_string_value(value);
400         assert_string_equal("ipv6:2001:db8::1:0:0:1:42", s);
401
402         value = json_object_get(object.root, "pipe");
403         assert_true(json_is_string(value));
404         s = json_string_value(value);
405         assert_string_equal("unix:/samba/pipe", s);
406
407         json_free(&object);
408         TALLOC_FREE(ctx);
409 }
410
411 static void test_json_add_sid(void **state)
412 {
413         struct json_object object;
414         struct json_t *value = NULL;
415         const char *SID = "S-1-5-21-2470180966-3899876309-2637894779";
416         struct dom_sid sid;
417         const char *s = NULL;
418
419
420         object = json_new_object();
421
422         json_add_sid(&object, "null", NULL);
423
424         assert_true(string_to_sid(&sid, SID));
425         json_add_sid(&object, "sid", &sid);
426
427         assert_int_equal(2, json_object_size(object.root));
428
429         value = json_object_get(object.root, "null");
430         assert_true(json_is_null(value));
431
432         value = json_object_get(object.root, "sid");
433         assert_true(json_is_string(value));
434         s = json_string_value(value);
435         assert_string_equal(SID, s);
436         json_free(&object);
437 }
438
439 static void test_json_add_guid(void **state)
440 {
441         struct json_object object;
442         struct json_t *value = NULL;
443         const char *GUID = "3ab88633-1e57-4c1a-856c-d1bc4b15bbb1";
444         struct GUID guid;
445         const char *s = NULL;
446         NTSTATUS status;
447
448
449         object = json_new_object();
450
451         json_add_guid(&object, "null", NULL);
452
453         status = GUID_from_string(GUID, &guid);
454         assert_true(NT_STATUS_IS_OK(status));
455         json_add_guid(&object, "guid", &guid);
456
457         assert_int_equal(2, json_object_size(object.root));
458
459         value = json_object_get(object.root, "null");
460         assert_true(json_is_null(value));
461
462         value = json_object_get(object.root, "guid");
463         assert_true(json_is_string(value));
464         s = json_string_value(value);
465         assert_string_equal(GUID, s);
466
467         json_free(&object);
468 }
469
470 static void test_json_to_string(void **state)
471 {
472         struct json_object object;
473         char *s = NULL;
474
475         TALLOC_CTX *ctx = talloc_new(NULL);
476
477         object = json_new_object();
478         object.error = true;
479
480         s = json_to_string(ctx, &object);
481         assert_null(s);
482
483         object.error = false;
484         s = json_to_string(ctx, &object);
485         assert_string_equal("{}", s);
486         TALLOC_FREE(s);
487
488         json_add_string(&object, "name", "value");
489         s = json_to_string(ctx, &object);
490         assert_string_equal("{\"name\": \"value\"}", s);
491         TALLOC_FREE(s);
492
493         json_free(&object);
494         TALLOC_FREE(ctx);
495 }
496
497 static void test_json_get_array(void **state)
498 {
499         struct json_object object;
500         struct json_object array;
501         struct json_object stored_array = json_new_array();
502         json_t *value = NULL;
503         json_t *o = NULL;
504         struct json_object o1;
505         struct json_object o2;
506
507         object = json_new_object();
508
509         array = json_get_array(&object, "not-there");
510         assert_false(array.error);
511         assert_non_null(array.root);
512         assert_true(json_is_array(array.root));
513         json_free(&array);
514
515         o1 = json_new_object();
516         json_add_string(&o1, "value", "value-one");
517         json_add_object(&stored_array, NULL, &o1);
518         json_add_object(&object, "stored_array", &stored_array);
519
520         array = json_get_array(&object, "stored_array");
521         assert_false(array.error);
522         assert_non_null(array.root);
523         assert_true(json_is_array(array.root));
524
525         assert_int_equal(1, json_array_size(array.root));
526
527         o = json_array_get(array.root, 0);
528         assert_non_null(o);
529         assert_true(json_is_object(o));
530
531         value = json_object_get(o, "value");
532         assert_non_null(value);
533         assert_true(json_is_string(value));
534
535         assert_string_equal("value-one", json_string_value(value));
536         json_free(&array);
537
538         /*
539          * Now update the array and add it back to the object
540          */
541         array = json_get_array(&object, "stored_array");
542         assert_true(json_is_array(array.root));
543         o2 = json_new_object();
544         json_add_string(&o2, "value", "value-two");
545         assert_false(o2.error);
546         json_add_object(&array, NULL, &o2);
547         assert_true(json_is_array(array.root));
548         json_add_object(&object, "stored_array", &array);
549         assert_true(json_is_array(array.root));
550
551         array = json_get_array(&object, "stored_array");
552         assert_non_null(array.root);
553         assert_true(json_is_array(array.root));
554         assert_false(array.error);
555         assert_true(json_is_array(array.root));
556
557         assert_int_equal(2, json_array_size(array.root));
558
559         o = json_array_get(array.root, 0);
560         assert_non_null(o);
561         assert_true(json_is_object(o));
562
563         assert_non_null(value);
564         assert_true(json_is_string(value));
565
566         assert_string_equal("value-one", json_string_value(value));
567
568         o = json_array_get(array.root, 1);
569         assert_non_null(o);
570         assert_true(json_is_object(o));
571
572         value = json_object_get(o, "value");
573         assert_non_null(value);
574         assert_true(json_is_string(value));
575
576         assert_string_equal("value-two", json_string_value(value));
577
578         json_free(&array);
579         json_free(&object);
580 }
581
582 static void test_json_get_object(void **state)
583 {
584         struct json_object object;
585         struct json_object o1;
586         struct json_object o2;
587         struct json_object o3;
588         json_t *value = NULL;
589
590         object = json_new_object();
591
592         o1 = json_get_object(&object, "not-there");
593         assert_false(o1.error);
594         assert_non_null(o1.root);
595         assert_true(json_is_object(o1.root));
596         json_free(&o1);
597
598         o1 = json_new_object();
599         json_add_string(&o1, "value", "value-one");
600         json_add_object(&object, "stored_object", &o1);
601
602         o2 = json_get_object(&object, "stored_object");
603         assert_false(o2.error);
604         assert_non_null(o2.root);
605         assert_true(json_is_object(o2.root));
606
607         value = json_object_get(o2.root, "value");
608         assert_non_null(value);
609         assert_true(json_is_string(value));
610
611         assert_string_equal("value-one", json_string_value(value));
612
613         json_add_string(&o2, "value", "value-two");
614         json_add_object(&object, "stored_object", &o2);
615
616
617         o3 = json_get_object(&object, "stored_object");
618         assert_false(o3.error);
619         assert_non_null(o3.root);
620         assert_true(json_is_object(o3.root));
621
622         value = json_object_get(o3.root, "value");
623         assert_non_null(value);
624         assert_true(json_is_string(value));
625
626         assert_string_equal("value-two", json_string_value(value));
627
628         json_free(&o3);
629         json_free(&object);
630 }
631
632 static void test_audit_get_timestamp(void **state)
633 {
634         const char *t = NULL;
635         char *c;
636         struct tm tm;
637         time_t before;
638         time_t after;
639         time_t actual;
640
641         TALLOC_CTX *ctx = talloc_new(NULL);
642
643         before = time(NULL);
644         t = audit_get_timestamp(ctx);
645         after = time(NULL);
646
647
648         c = strptime(t, "%a, %d %b %Y %H:%M:%S", &tm);
649         tm.tm_isdst = -1;
650         if (c != NULL && *c == '.') {
651                 char *e;
652                 strtod(c, &e);
653                 c = e;
654         }
655         if (c != NULL && *c == ' ') {
656                 struct tm tz;
657                 c = strptime(c, " %Z", &tz);
658         }
659         assert_non_null(c);
660         assert_int_equal(0, strlen(c));
661
662         actual = mktime(&tm);
663
664         /*
665          * The timestamp should be before <= actual <= after
666          */
667         assert_true(difftime(actual, before) >= 0);
668         assert_true(difftime(after, actual) >= 0);
669
670         TALLOC_FREE(ctx);
671 }
672
673 int main(int argc, const char **argv)
674 {
675         const struct CMUnitTest tests[] = {
676                 cmocka_unit_test(test_json_add_int),
677                 cmocka_unit_test(test_json_add_bool),
678                 cmocka_unit_test(test_json_add_string),
679                 cmocka_unit_test(test_json_add_object),
680                 cmocka_unit_test(test_json_add_to_array),
681                 cmocka_unit_test(test_json_add_timestamp),
682                 cmocka_unit_test(test_json_add_stringn),
683                 cmocka_unit_test(test_json_add_version),
684                 cmocka_unit_test(test_json_add_address),
685                 cmocka_unit_test(test_json_add_sid),
686                 cmocka_unit_test(test_json_add_guid),
687                 cmocka_unit_test(test_json_to_string),
688                 cmocka_unit_test(test_json_get_array),
689                 cmocka_unit_test(test_json_get_object),
690                 cmocka_unit_test(test_audit_get_timestamp),
691         };
692
693         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
694         return cmocka_run_group_tests(tests, NULL, NULL);
695 }