docs: Document new tdbdump -x option
[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(_UNUSED_ void **state)
63 {
64         struct json_object object;
65         struct json_t *value = NULL;
66         json_int_t m;
67         double n;
68         int rc = 0;
69         intmax_t big_int = ((intmax_t)1)<<33;
70
71         object = json_new_object();
72         assert_false(json_is_invalid(&object));
73         rc = json_add_int(&object, "positive_one", 1);
74         assert_int_equal(0, rc);
75         rc = json_add_int(&object, "zero", 0);
76         assert_int_equal(0, rc);
77         rc = json_add_int(&object, "negative_one", -1);
78         assert_int_equal(0, rc);
79         rc = json_add_int(&object, "big_int", big_int);
80         assert_int_equal(0, rc);
81
82         assert_int_equal(4, json_object_size(object.root));
83
84         value = json_object_get(object.root, "positive_one");
85         assert_true(json_is_integer(value));
86         n = json_number_value(value);
87         assert_true(n == 1.0);
88
89         value = json_object_get(object.root, "zero");
90         assert_true(json_is_integer(value));
91         n = json_number_value(value);
92         assert_true(n == 0.0);
93
94         value = json_object_get(object.root, "negative_one");
95         assert_true(json_is_integer(value));
96         n = json_number_value(value);
97         assert_true(n == -1.0);
98
99         value = json_object_get(object.root, "big_int");
100         assert_true(json_is_integer(value));
101         m = json_integer_value(value);
102         assert_int_equal(m, big_int);
103
104         object.valid = false;
105         rc = json_add_int(&object, "should fail 1", 0xf1);
106         assert_int_equal(JSON_ERROR, rc);
107
108         json_free(&object);
109
110         rc = json_add_int(&object, "should fail 2", 0xf2);
111         assert_int_equal(JSON_ERROR, rc);
112 }
113
114 static void test_json_add_bool(_UNUSED_ void **state)
115 {
116         struct json_object object;
117         struct json_t *value = NULL;
118         int rc = 0;
119
120         object = json_new_object();
121         assert_false(json_is_invalid(&object));
122         rc = json_add_bool(&object, "true", true);
123         assert_int_equal(0, rc);
124         rc = json_add_bool(&object, "false", false);
125         assert_int_equal(0, rc);
126
127         assert_int_equal(2, json_object_size(object.root));
128
129         value = json_object_get(object.root, "true");
130         assert_true(json_is_boolean(value));
131         assert_true(value == json_true());
132
133         value = json_object_get(object.root, "false");
134         assert_true(json_is_boolean(value));
135         assert_true(value == json_false());
136
137         object.valid = false;
138         rc = json_add_bool(&object, "should fail 1", true);
139         assert_int_equal(JSON_ERROR, rc);
140
141         json_free(&object);
142
143         rc = json_add_bool(&object, "should fail 2", false);
144         assert_int_equal(JSON_ERROR, rc);
145 }
146
147 static void test_json_add_string(_UNUSED_ void **state)
148 {
149         struct json_object object;
150         struct json_t *value = NULL;
151         const char *s = NULL;
152         int rc = 0;
153
154         object = json_new_object();
155         assert_false(json_is_invalid(&object));
156         rc = json_add_string(&object, "null", NULL);
157         assert_int_equal(0, rc);
158         rc = json_add_string(&object, "empty", "");
159         assert_int_equal(0, rc);
160         rc = json_add_string(&object, "name", "value");
161         assert_int_equal(0, rc);
162
163         assert_int_equal(3, json_object_size(object.root));
164
165         value = json_object_get(object.root, "null");
166         assert_true(json_is_null(value));
167
168         value = json_object_get(object.root, "empty");
169         assert_true(json_is_string(value));
170         s = json_string_value(value);
171         assert_string_equal("", s);
172
173         value = json_object_get(object.root, "name");
174         assert_true(json_is_string(value));
175         s = json_string_value(value);
176         assert_string_equal("value", s);
177
178         object.valid = false;
179         rc = json_add_string(&object, "should fail 1", "A value");
180         assert_int_equal(JSON_ERROR, rc);
181
182         json_free(&object);
183
184         rc = json_add_string(&object, "should fail 2", "Another value");
185         assert_int_equal(JSON_ERROR, rc);
186 }
187
188 static void test_json_add_object(_UNUSED_ void **state)
189 {
190         struct json_object object;
191         struct json_object other;
192         struct json_object after;
193         struct json_object invalid = json_empty_object;
194         struct json_t *value = NULL;
195         int rc = 0;
196
197         object = json_new_object();
198         assert_false(json_is_invalid(&object));
199         other  = json_new_object();
200         assert_false(json_is_invalid(&other));
201         rc = json_add_object(&object, "null", NULL);
202         assert_int_equal(0, rc);
203         rc = json_add_object(&object, "other", &other);
204         assert_int_equal(0, rc);
205
206         assert_int_equal(2, json_object_size(object.root));
207
208         value = json_object_get(object.root, "null");
209         assert_true(json_is_null(value));
210
211         value = json_object_get(object.root, "other");
212         assert_true(json_is_object(value));
213         assert_ptr_equal(other.root, value);
214
215         rc = json_add_object(&object, "invalid", &invalid);
216         assert_int_equal(JSON_ERROR, rc);
217
218         object.valid = false;
219         after = json_new_object();
220         assert_false(json_is_invalid(&after));
221         rc = json_add_object(&object, "after", &after);
222         assert_int_equal(JSON_ERROR, rc);
223
224         json_free(&object);
225
226         rc = json_add_object(&object, "after", &after);
227         assert_int_equal(JSON_ERROR, rc);
228
229         json_free(&after);
230 }
231
232 static void test_json_add_to_array(_UNUSED_ void **state)
233 {
234         struct json_object array;
235         struct json_object o1;
236         struct json_object o2;
237         struct json_object o3;
238         struct json_object after;
239         struct json_object invalid = json_empty_object;
240         struct json_t *value = NULL;
241         int rc = 0;
242
243         array = json_new_array();
244         assert_false(json_is_invalid(&array));
245         assert_true(json_is_array(array.root));
246
247         o1 = json_new_object();
248         assert_false(json_is_invalid(&o1));
249         o2 = json_new_object();
250         assert_false(json_is_invalid(&o2));
251         o3 = json_new_object();
252         assert_false(json_is_invalid(&o3));
253
254         rc = json_add_object(&array, NULL, &o3);
255         assert_int_equal(0, rc);
256         rc = json_add_object(&array, "", &o2);
257         assert_int_equal(0, rc);
258         rc = json_add_object(&array, "will-be-ignored", &o1);
259         assert_int_equal(0, rc);
260         rc = json_add_object(&array, NULL, NULL);
261         assert_int_equal(0, rc);
262
263         assert_int_equal(4, json_array_size(array.root));
264
265         value = json_array_get(array.root, 0);
266         assert_ptr_equal(o3.root, value);
267
268         value = json_array_get(array.root, 1);
269         assert_ptr_equal(o2.root, value);
270
271         value = json_array_get(array.root, 2);
272         assert_ptr_equal(o1.root, value);
273
274         value = json_array_get(array.root, 3);
275         assert_true(json_is_null(value));
276
277         rc = json_add_object(&array, "invalid", &invalid);
278         assert_int_equal(JSON_ERROR, rc);
279
280         array.valid = false;
281         after = json_new_object();
282         assert_false(json_is_invalid(&after));
283         rc = json_add_object(&array, "after", &after);
284         assert_int_equal(JSON_ERROR, rc);
285
286         json_free(&array);
287
288         rc = json_add_object(&array, "after", &after);
289         assert_int_equal(JSON_ERROR, rc);
290
291         json_free(&after);
292 }
293
294 static void test_json_add_timestamp(_UNUSED_ void **state)
295 {
296         struct json_object object;
297         struct json_t *ts = NULL;
298         const char *t = NULL;
299         int rc;
300         int usec, tz;
301         char c[2];
302         struct tm tm;
303         time_t before;
304         time_t after;
305         time_t actual;
306         struct timeval tv;
307         int ret;
308
309         object = json_new_object();
310         assert_false(json_is_invalid(&object));
311
312         ret = gettimeofday(&tv, NULL);
313         assert_int_equal(0, ret);
314         before = tv.tv_sec;
315
316         rc = json_add_timestamp(&object);
317         assert_int_equal(0, rc);
318
319         ret = gettimeofday(&tv, NULL);
320         assert_int_equal(0, ret);
321         after = tv.tv_sec;
322
323         ts = json_object_get(object.root, "timestamp");
324         assert_true(json_is_string(ts));
325
326         /*
327          * Convert the returned ISO 8601 timestamp into a time_t
328          * Note for convenience we ignore the value of the microsecond
329          * part of the time stamp.
330          */
331         t = json_string_value(ts);
332         rc = sscanf(
333                 t,
334                 "%4d-%2d-%2dT%2d:%2d:%2d.%6d%1c%4d",
335                 &tm.tm_year,
336                 &tm.tm_mon,
337                 &tm.tm_mday,
338                 &tm.tm_hour,
339                 &tm.tm_min,
340                 &tm.tm_sec,
341                 &usec,
342                 c,
343                 &tz);
344         assert_int_equal(9, rc);
345         tm.tm_year = tm.tm_year - 1900;
346         tm.tm_mon = tm.tm_mon - 1;
347         tm.tm_isdst = -1;
348         actual = mktime(&tm);
349
350         /*
351          * The timestamp should be before <= actual <= after
352          */
353         assert_true(difftime(actual, before) >= 0);
354         assert_true(difftime(after, actual) >= 0);
355
356         object.valid = false;
357         rc = json_add_timestamp(&object);
358         assert_int_equal(JSON_ERROR, rc);
359
360         json_free(&object);
361
362         rc = json_add_timestamp(&object);
363         assert_int_equal(JSON_ERROR, rc);
364 }
365
366 static void test_json_add_stringn(_UNUSED_ void **state)
367 {
368         struct json_object object;
369         struct json_t *value = NULL;
370         const char *s = NULL;
371         int rc = 0;
372
373         object = json_new_object();
374         assert_false(json_is_invalid(&object));
375         rc = json_add_stringn(&object, "null", NULL, 10);
376         assert_int_equal(0, rc);
377         rc = json_add_stringn(&object, "null-zero-len", NULL, 0);
378         assert_int_equal(0, rc);
379         rc = json_add_stringn(&object, "empty", "", 1);
380         assert_int_equal(0, rc);
381         rc = json_add_stringn(&object, "empty-zero-len", "", 0);
382         assert_int_equal(0, rc);
383         rc = json_add_stringn(&object, "value-less-than-len", "123456", 7);
384         assert_int_equal(0, rc);
385         rc = json_add_stringn(&object, "value-greater-than-len", "abcd", 3);
386         assert_int_equal(0, rc);
387         rc = json_add_stringn(&object, "value-equal-len", "ZYX", 3);
388         assert_int_equal(0, rc);
389         rc = json_add_stringn(
390             &object, "value-len-is-zero", "this will be null", 0);
391         assert_int_equal(0, rc);
392
393         assert_int_equal(8, json_object_size(object.root));
394
395         value = json_object_get(object.root, "null");
396         assert_true(json_is_null(value));
397
398         value = json_object_get(object.root, "null-zero-len");
399         assert_true(json_is_null(value));
400
401         value = json_object_get(object.root, "empty");
402         assert_true(json_is_string(value));
403         s = json_string_value(value);
404         assert_string_equal("", s);
405
406         value = json_object_get(object.root, "empty-zero-len");
407         assert_true(json_is_null(value));
408
409         value = json_object_get(object.root, "value-greater-than-len");
410         assert_true(json_is_string(value));
411         s = json_string_value(value);
412         assert_string_equal("abc", s);
413         assert_int_equal(3, strlen(s));
414
415         value = json_object_get(object.root, "value-equal-len");
416         assert_true(json_is_string(value));
417         s = json_string_value(value);
418         assert_string_equal("ZYX", s);
419         assert_int_equal(3, strlen(s));
420
421         value = json_object_get(object.root, "value-len-is-zero");
422         assert_true(json_is_null(value));
423
424         object.valid = false;
425         rc = json_add_stringn(&object, "fail-01", "xxxxxxx", 1);
426         assert_int_equal(JSON_ERROR, rc);
427
428         json_free(&object);
429
430         rc = json_add_stringn(&object, "fail-02", "xxxxxxx", 1);
431         assert_int_equal(JSON_ERROR, rc);
432 }
433
434 static void test_json_add_version(_UNUSED_ void **state)
435 {
436         struct json_object object;
437         struct json_t *version = NULL;
438         struct json_t *v = NULL;
439         double n;
440         int rc;
441
442         object = json_new_object();
443         assert_false(json_is_invalid(&object));
444         rc = json_add_version(&object, 3, 1);
445         assert_int_equal(0, rc);
446
447         assert_int_equal(1, json_object_size(object.root));
448
449         version = json_object_get(object.root, "version");
450         assert_true(json_is_object(version));
451         assert_int_equal(2, json_object_size(version));
452
453         v = json_object_get(version, "major");
454         assert_true(json_is_integer(v));
455         n = json_number_value(v);
456         assert_true(n == 3.0);
457
458         v = json_object_get(version, "minor");
459         assert_true(json_is_integer(v));
460         n = json_number_value(v);
461         assert_true(n == 1.0);
462
463         object.valid = false;
464         rc = json_add_version(&object, 3, 1);
465         assert_int_equal(JSON_ERROR, rc);
466
467         json_free(&object);
468
469         rc = json_add_version(&object, 3, 1);
470         assert_int_equal(JSON_ERROR, rc);
471 }
472
473 static void test_json_add_address(_UNUSED_ void **state)
474 {
475         struct json_object object;
476         struct json_t *value = NULL;
477         struct tsocket_address *ip4  = NULL;
478         struct tsocket_address *ip6  = NULL;
479         struct tsocket_address *pipe = NULL;
480
481         struct tsocket_address *after = NULL;
482         const char *s = NULL;
483         int rc;
484
485         TALLOC_CTX *ctx = talloc_new(NULL);
486
487         object = json_new_object();
488         assert_false(json_is_invalid(&object));
489
490         rc = json_add_address(&object, "null", NULL);
491         assert_int_equal(0, rc);
492
493         rc = tsocket_address_inet_from_strings(
494                 ctx,
495                 "ip",
496                 "127.0.0.1",
497                 21,
498                 &ip4);
499         assert_int_equal(0, rc);
500         rc = json_add_address(&object, "ip4", ip4);
501         assert_int_equal(0, rc);
502
503         rc = tsocket_address_inet_from_strings(
504                 ctx,
505                 "ip",
506                 "2001:db8:0:0:1:0:0:1",
507                 42,
508                 &ip6);
509         assert_int_equal(0, rc);
510         rc = json_add_address(&object, "ip6", ip6);
511         assert_int_equal(0, rc);
512
513         rc = tsocket_address_unix_from_path(ctx, "/samba/pipe", &pipe);
514         assert_int_equal(0, rc);
515         rc = json_add_address(&object, "pipe", pipe);
516         assert_int_equal(0, rc);
517
518         assert_int_equal(4, json_object_size(object.root));
519
520         value = json_object_get(object.root, "null");
521         assert_true(json_is_null(value));
522
523         value = json_object_get(object.root, "ip4");
524         assert_true(json_is_string(value));
525         s = json_string_value(value);
526         assert_string_equal("ipv4:127.0.0.1:21", s);
527
528         value = json_object_get(object.root, "ip6");
529         assert_true(json_is_string(value));
530         s = json_string_value(value);
531         assert_string_equal("ipv6:2001:db8::1:0:0:1:42", s);
532
533         value = json_object_get(object.root, "pipe");
534         assert_true(json_is_string(value));
535         s = json_string_value(value);
536         assert_string_equal("unix:/samba/pipe", s);
537
538         object.valid = false;
539         rc = tsocket_address_inet_from_strings(
540             ctx, "ip", "127.0.0.11", 23, &after);
541         assert_int_equal(0, rc);
542         rc = json_add_address(&object, "invalid_object", after);
543         assert_int_equal(JSON_ERROR, rc);
544
545         json_free(&object);
546
547         rc = json_add_address(&object, "freed object", after);
548         assert_int_equal(JSON_ERROR, rc);
549
550         TALLOC_FREE(ctx);
551 }
552
553 static void test_json_add_sid(_UNUSED_ void **state)
554 {
555         struct json_object object;
556         struct json_t *value = NULL;
557         const char *SID = "S-1-5-21-2470180966-3899876309-2637894779";
558         struct dom_sid sid;
559         const char *s = NULL;
560         int rc;
561
562         object = json_new_object();
563         assert_false(json_is_invalid(&object));
564
565         rc = json_add_sid(&object, "null", NULL);
566         assert_int_equal(0, rc);
567
568         assert_true(string_to_sid(&sid, SID));
569         rc = json_add_sid(&object, "sid", &sid);
570         assert_int_equal(0, rc);
571
572         assert_int_equal(2, json_object_size(object.root));
573
574         value = json_object_get(object.root, "null");
575         assert_true(json_is_null(value));
576
577         value = json_object_get(object.root, "sid");
578         assert_true(json_is_string(value));
579         s = json_string_value(value);
580         assert_string_equal(SID, s);
581
582         object.valid = false;
583         rc = json_add_sid(&object, "invalid_object", &sid);
584         assert_int_equal(JSON_ERROR, rc);
585
586         json_free(&object);
587
588         rc = json_add_sid(&object, "freed_object", &sid);
589         assert_int_equal(JSON_ERROR, rc);
590 }
591
592 static void test_json_add_guid(_UNUSED_ void **state)
593 {
594         struct json_object object;
595         struct json_t *value = NULL;
596         const char *GUID = "3ab88633-1e57-4c1a-856c-d1bc4b15bbb1";
597         struct GUID guid;
598         const char *s = NULL;
599         NTSTATUS status;
600         int rc;
601
602         object = json_new_object();
603         assert_false(json_is_invalid(&object));
604
605         rc = json_add_guid(&object, "null", NULL);
606         assert_int_equal(0, rc);
607
608         status = GUID_from_string(GUID, &guid);
609         assert_true(NT_STATUS_IS_OK(status));
610         rc = json_add_guid(&object, "guid", &guid);
611         assert_int_equal(0, rc);
612
613         assert_int_equal(2, json_object_size(object.root));
614
615         value = json_object_get(object.root, "null");
616         assert_true(json_is_null(value));
617
618         value = json_object_get(object.root, "guid");
619         assert_true(json_is_string(value));
620         s = json_string_value(value);
621         assert_string_equal(GUID, s);
622
623         object.valid = false;
624         rc = json_add_guid(&object, "invalid_object", &guid);
625         assert_int_equal(JSON_ERROR, rc);
626
627         json_free(&object);
628
629         rc = json_add_guid(&object, "freed_object", &guid);
630         assert_int_equal(JSON_ERROR, rc);
631 }
632
633 static void test_json_to_string(_UNUSED_ void **state)
634 {
635         struct json_object object;
636         char *s = NULL;
637         int rc;
638
639         TALLOC_CTX *ctx = talloc_new(NULL);
640
641         object = json_new_object();
642         assert_false(json_is_invalid(&object));
643
644         s = json_to_string(ctx, &object);
645         assert_string_equal("{}", s);
646         TALLOC_FREE(s);
647
648         rc = json_add_string(&object, "name", "value");
649         assert_int_equal(0, rc);
650         s = json_to_string(ctx, &object);
651         assert_string_equal("{\"name\": \"value\"}", s);
652         TALLOC_FREE(s);
653
654         object.valid = false;
655         s = json_to_string(ctx, &object);
656         assert_null(s);
657
658         json_free(&object);
659
660         object.valid = true;
661         object.root = NULL;
662
663         s = json_to_string(ctx, &object);
664         assert_null(s);
665         TALLOC_FREE(ctx);
666 }
667
668 static void test_json_get_array(_UNUSED_ void **state)
669 {
670         struct json_object object;
671         struct json_object array;
672         struct json_object stored_array = json_new_array();
673         json_t *value = NULL;
674         json_t *o = NULL;
675         struct json_object o1;
676         struct json_object o2;
677         int rc;
678
679         assert_false(json_is_invalid(&stored_array));
680
681         object = json_new_object();
682         assert_false(json_is_invalid(&object));
683
684         array = json_get_array(&object, "not-there");
685         assert_true(array.valid);
686         assert_non_null(array.root);
687         assert_true(json_is_array(array.root));
688         json_free(&array);
689
690         o1 = json_new_object();
691         assert_false(json_is_invalid(&o1));
692         rc = json_add_string(&o1, "value", "value-one");
693         assert_int_equal(0, rc);
694         rc = json_add_object(&stored_array, NULL, &o1);
695         assert_int_equal(0, rc);
696         rc = json_add_object(&object, "stored_array", &stored_array);
697         assert_int_equal(0, rc);
698
699         array = json_get_array(&object, "stored_array");
700         assert_true(array.valid);
701         assert_non_null(array.root);
702         assert_true(json_is_array(array.root));
703
704         assert_int_equal(1, json_array_size(array.root));
705
706         o = json_array_get(array.root, 0);
707         assert_non_null(o);
708         assert_true(json_is_object(o));
709
710         value = json_object_get(o, "value");
711         assert_non_null(value);
712         assert_true(json_is_string(value));
713
714         assert_string_equal("value-one", json_string_value(value));
715         json_free(&array);
716
717         /*
718          * Now update the array and add it back to the object
719          */
720         array = json_get_array(&object, "stored_array");
721         assert_true(json_is_array(array.root));
722         o2 = json_new_object();
723         assert_false(json_is_invalid(&o2));
724         rc = json_add_string(&o2, "value", "value-two");
725         assert_int_equal(0, rc);
726         assert_true(o2.valid);
727         rc = json_add_object(&array, NULL, &o2);
728         assert_int_equal(0, rc);
729         assert_true(json_is_array(array.root));
730         rc = json_add_object(&object, "stored_array", &array);
731         assert_int_equal(0, rc);
732         assert_true(json_is_array(array.root));
733
734         array = json_get_array(&object, "stored_array");
735         assert_non_null(array.root);
736         assert_true(json_is_array(array.root));
737         assert_true(array.valid);
738         assert_true(json_is_array(array.root));
739
740         assert_int_equal(2, json_array_size(array.root));
741
742         o = json_array_get(array.root, 0);
743         assert_non_null(o);
744         assert_true(json_is_object(o));
745
746         assert_non_null(value);
747         assert_true(json_is_string(value));
748
749         assert_string_equal("value-one", json_string_value(value));
750
751         o = json_array_get(array.root, 1);
752         assert_non_null(o);
753         assert_true(json_is_object(o));
754
755         value = json_object_get(o, "value");
756         assert_non_null(value);
757         assert_true(json_is_string(value));
758
759         assert_string_equal("value-two", json_string_value(value));
760
761         json_free(&array);
762         json_free(&object);
763
764         array = json_get_array(&object, "stored_array");
765         assert_false(array.valid);
766         json_free(&array);
767 }
768
769 static void test_json_get_object(_UNUSED_ void **state)
770 {
771         struct json_object object;
772         struct json_object o1;
773         struct json_object o2;
774         struct json_object o3;
775         json_t *value = NULL;
776         int rc;
777
778         object = json_new_object();
779         assert_false(json_is_invalid(&object));
780
781         o1 = json_get_object(&object, "not-there");
782         assert_true(o1.valid);
783         assert_non_null(o1.root);
784         assert_true(json_is_object(o1.root));
785         json_free(&o1);
786
787         o1 = json_new_object();
788         assert_false(json_is_invalid(&o1));
789         rc = json_add_string(&o1, "value", "value-one");
790         assert_int_equal(0, rc);
791         rc = json_add_object(&object, "stored_object", &o1);
792         assert_int_equal(0, rc);
793
794         o2 = json_get_object(&object, "stored_object");
795         assert_true(o2.valid);
796         assert_non_null(o2.root);
797         assert_true(json_is_object(o2.root));
798
799         value = json_object_get(o2.root, "value");
800         assert_non_null(value);
801         assert_true(json_is_string(value));
802
803         assert_string_equal("value-one", json_string_value(value));
804
805         rc = json_add_string(&o2, "value", "value-two");
806         assert_int_equal(0, rc);
807         rc = json_add_object(&object, "stored_object", &o2);
808         assert_int_equal(0, rc);
809
810         o3 = json_get_object(&object, "stored_object");
811         assert_true(o3.valid);
812         assert_non_null(o3.root);
813         assert_true(json_is_object(o3.root));
814
815         value = json_object_get(o3.root, "value");
816         assert_non_null(value);
817         assert_true(json_is_string(value));
818
819         assert_string_equal("value-two", json_string_value(value));
820
821         json_free(&o3);
822         json_free(&object);
823
824         o3 = json_get_object(&object, "stored_object");
825         assert_false(o3.valid);
826         json_free(&o3);
827 }
828
829 static void test_audit_get_timestamp(_UNUSED_ void **state)
830 {
831         const char *t = NULL;
832         char *c;
833         struct tm tm = {};
834         time_t before;
835         time_t after;
836         time_t actual;
837         struct timeval tv;
838         int ret;
839         char *env_tz = NULL;
840         char *orig_tz = NULL;
841
842         TALLOC_CTX *ctx = talloc_new(NULL);
843
844         /*
845          * Explicitly set the time zone to UTC to make the test easier
846          */
847         env_tz = getenv("TZ");
848         if (env_tz != NULL) {
849                 orig_tz = talloc_strdup(ctx, env_tz);
850         }
851         setenv("TZ", "UTC", 1);
852
853         ret = gettimeofday(&tv, NULL);
854         assert_int_equal(0, ret);
855         before = tv.tv_sec;
856
857         t = audit_get_timestamp(ctx);
858
859         ret = gettimeofday(&tv, NULL);
860         assert_int_equal(0, ret);
861         after = tv.tv_sec;
862
863         c = strptime(t, "%a, %d %b %Y %H:%M:%S", &tm);
864
865         /*
866          * Restore the time zone if we changed it
867          */
868         if (orig_tz != NULL) {
869                 setenv("TZ", orig_tz, 1);
870                 TALLOC_FREE(orig_tz);
871         }
872
873         assert_non_null(c);
874         tm.tm_isdst = -1;
875         if (c != NULL && *c == '.') {
876                 char *e;
877                 strtod(c, &e);
878                 c = e;
879         }
880         if (c != NULL && *c == ' ') {
881                 assert_string_equal(" UTC", c);
882                 c += 4;
883         }
884         assert_int_equal(0, strlen(c));
885
886         actual = mktime(&tm);
887
888         /*
889          * The timestamp should be before <= actual <= after
890          */
891         assert_true(difftime(actual, before) >= 0);
892         assert_true(difftime(after, actual) >= 0);
893
894         TALLOC_FREE(ctx);
895 }
896
897 int main(_UNUSED_ int argc, _UNUSED_ const char **argv)
898 {
899         const struct CMUnitTest tests[] = {
900                 cmocka_unit_test(test_json_add_int),
901                 cmocka_unit_test(test_json_add_bool),
902                 cmocka_unit_test(test_json_add_string),
903                 cmocka_unit_test(test_json_add_object),
904                 cmocka_unit_test(test_json_add_to_array),
905                 cmocka_unit_test(test_json_add_timestamp),
906                 cmocka_unit_test(test_json_add_stringn),
907                 cmocka_unit_test(test_json_add_version),
908                 cmocka_unit_test(test_json_add_address),
909                 cmocka_unit_test(test_json_add_sid),
910                 cmocka_unit_test(test_json_add_guid),
911                 cmocka_unit_test(test_json_to_string),
912                 cmocka_unit_test(test_json_get_array),
913                 cmocka_unit_test(test_json_get_object),
914                 cmocka_unit_test(test_audit_get_timestamp),
915         };
916
917         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
918         return cmocka_run_group_tests(tests, NULL, NULL);
919 }