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