dsdb: Audit group membership changes
[nivanova/samba-autobuild/.git] / source4 / dsdb / samdb / ldb_modules / tests / test_group_audit.c
1 /*
2    Unit tests for the dsdb group auditing code in group_audit.c
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 #include <stdarg.h>
21 #include <stddef.h>
22 #include <setjmp.h>
23 #include <unistd.h>
24 #include <cmocka.h>
25
26 int ldb_group_audit_log_module_init(const char *version);
27 #include "../group_audit.c"
28
29 #include "lib/ldb/include/ldb_private.h"
30 #include <regex.h>
31
32 /*
33  * Mock version of dsdb_search_one
34  */
35 struct ldb_dn *g_basedn = NULL;
36 enum ldb_scope g_scope;
37 const char * const *g_attrs = NULL;
38 uint32_t g_dsdb_flags;
39 const char *g_exp_fmt;
40 const char *g_dn = NULL;
41 int g_status = LDB_SUCCESS;
42
43 int dsdb_search_one(struct ldb_context *ldb,
44                     TALLOC_CTX *mem_ctx,
45                     struct ldb_message **msg,
46                     struct ldb_dn *basedn,
47                     enum ldb_scope scope,
48                     const char * const *attrs,
49                     uint32_t dsdb_flags,
50                     const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(8, 9)
51 {
52         struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, g_dn);
53         struct ldb_message *m = talloc_zero(mem_ctx, struct ldb_message);
54         m->dn = dn;
55         *msg = m;
56
57         g_basedn = basedn;
58         g_scope = scope;
59         g_attrs = attrs;
60         g_dsdb_flags = dsdb_flags;
61         g_exp_fmt = exp_fmt;
62
63         return g_status;
64 }
65
66 /*
67  * Mocking for audit_log_hr to capture the called parameters
68  */
69 const char *audit_log_hr_prefix = NULL;
70 const char *audit_log_hr_message = NULL;
71 int audit_log_hr_debug_class = 0;
72 int audit_log_hr_debug_level = 0;
73
74 static void audit_log_hr_init(void)
75 {
76         audit_log_hr_prefix = NULL;
77         audit_log_hr_message = NULL;
78         audit_log_hr_debug_class = 0;
79         audit_log_hr_debug_level = 0;
80 }
81
82 void audit_log_human_text(
83         const char *prefix,
84         const char *message,
85         int debug_class,
86         int debug_level)
87 {
88         audit_log_hr_prefix = prefix;
89         audit_log_hr_message = message;
90         audit_log_hr_debug_class = debug_class;
91         audit_log_hr_debug_level = debug_level;
92 }
93
94 /*
95  * Test helper to check ISO 8601 timestamps for validity
96  */
97 static void check_timestamp(time_t before, const char *timestamp)
98 {
99         int rc;
100         int usec, tz;
101         char c[2];
102         struct tm tm;
103         time_t after;
104         time_t actual;
105
106
107         after = time(NULL);
108
109         /*
110          * Convert the ISO 8601 timestamp into a time_t
111          * Note for convenience we ignore the value of the microsecond
112          * part of the time stamp.
113          */
114         rc = sscanf(
115                 timestamp,
116                 "%4d-%2d-%2dT%2d:%2d:%2d.%6d%1c%4d",
117                 &tm.tm_year,
118                 &tm.tm_mon,
119                 &tm.tm_mday,
120                 &tm.tm_hour,
121                 &tm.tm_min,
122                 &tm.tm_sec,
123                 &usec,
124                 c,
125                 &tz);
126         assert_int_equal(9, rc);
127         tm.tm_year = tm.tm_year - 1900;
128         tm.tm_mon = tm.tm_mon - 1;
129         tm.tm_isdst = -1;
130         actual = mktime(&tm);
131
132         /*
133          * The timestamp should be before <= actual <= after
134          */
135         assert_true(difftime(actual, before) >= 0);
136         assert_true(difftime(after, actual) >= 0);
137 }
138
139 /*
140  * Test helper to validate a version object.
141  */
142 static void check_version(struct json_t *version, int major, int minor)
143 {
144         struct json_t *v = NULL;
145
146         assert_true(json_is_object(version));
147         assert_int_equal(2, json_object_size(version));
148
149         v = json_object_get(version, "major");
150         assert_non_null(v);
151         assert_int_equal(major, json_integer_value(v));
152
153         v = json_object_get(version, "minor");
154         assert_non_null(v);
155         assert_int_equal(minor, json_integer_value(v));
156 }
157
158 /*
159  * Test helper to insert a transaction_id into a request.
160  */
161 static void add_transaction_id(struct ldb_request *req, const char *id)
162 {
163         struct GUID guid;
164         struct dsdb_control_transaction_identifier *transaction_id = NULL;
165
166         transaction_id = talloc_zero(
167                 req,
168                 struct dsdb_control_transaction_identifier);
169         assert_non_null(transaction_id);
170         GUID_from_string(id, &guid);
171         transaction_id->transaction_guid = guid;
172         ldb_request_add_control(
173                 req,
174                 DSDB_CONTROL_TRANSACTION_IDENTIFIER_OID,
175                 false,
176                 transaction_id);
177 }
178
179 /*
180  * Test helper to add a session id and user SID
181  */
182 static void add_session_data(
183         TALLOC_CTX *ctx,
184         struct ldb_context *ldb,
185         const char *session,
186         const char *user_sid)
187 {
188         struct auth_session_info *sess = NULL;
189         struct security_token *token = NULL;
190         struct dom_sid *sid = NULL;
191         struct GUID session_id;
192
193         sess = talloc_zero(ctx, struct auth_session_info);
194         token = talloc_zero(ctx, struct security_token);
195         sid = talloc_zero(ctx, struct dom_sid);
196         string_to_sid(sid, user_sid);
197         token->sids = sid;
198         sess->security_token = token;
199         GUID_from_string(session, &session_id);
200         sess->unique_session_token = session_id;
201         ldb_set_opaque(ldb, "sessionInfo", sess);
202 }
203
204 static void test_get_transaction_id(void **state)
205 {
206         struct ldb_request *req = NULL;
207         struct GUID *guid;
208         const char * const ID = "7130cb06-2062-6a1b-409e-3514c26b1773";
209         char *guid_str = NULL;
210         struct GUID_txt_buf guid_buff;
211
212
213         TALLOC_CTX *ctx = talloc_new(NULL);
214
215
216         /*
217          * No transaction id, should return a zero guid
218          */
219         req = talloc_zero(ctx, struct ldb_request);
220         guid = get_transaction_id(req);
221         assert_null(guid);
222         TALLOC_FREE(req);
223
224         /*
225          * And now test with the transaction_id set
226          */
227         req = talloc_zero(ctx, struct ldb_request);
228         assert_non_null(req);
229         add_transaction_id(req, ID);
230
231         guid = get_transaction_id(req);
232         guid_str = GUID_buf_string(guid, &guid_buff);
233         assert_string_equal(ID, guid_str);
234         TALLOC_FREE(req);
235
236         TALLOC_FREE(ctx);
237 }
238
239 static void test_audit_group_hr(void **state)
240 {
241         struct ldb_context *ldb = NULL;
242         struct ldb_module  *module = NULL;
243         struct ldb_request *req = NULL;
244
245         struct tsocket_address *ts = NULL;
246
247         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
248         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
249
250         struct GUID transaction_id;
251         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
252
253
254         char *line = NULL;
255         const char *rs = NULL;
256         regex_t regex;
257         int ret;
258
259
260         TALLOC_CTX *ctx = talloc_new(NULL);
261
262         ldb = talloc_zero(ctx, struct ldb_context);
263
264         GUID_from_string(TRANSACTION, &transaction_id);
265
266         module = talloc_zero(ctx, struct ldb_module);
267         module->ldb = ldb;
268
269         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
270         ldb_set_opaque(ldb, "remoteAddress", ts);
271
272         add_session_data(ctx, ldb, SESSION, SID);
273
274         req = talloc_zero(ctx, struct ldb_request);
275         req->operation =  LDB_ADD;
276         add_transaction_id(req, TRANSACTION);
277
278         line = audit_group_human_readable(
279                 ctx,
280                 module,
281                 req,
282                 "the-action",
283                 "the-user-name",
284                 "the-group-name",
285                 LDB_ERR_OPERATIONS_ERROR);
286         assert_non_null(line);
287
288         rs =    "\\[the-action\\] at \\["
289                 "[^]]*"
290                 "\\] status \\[Operations error\\] "
291                 "Remote host \\[ipv4:127.0.0.1:0\\] "
292                 "SID \\[S-1-5-21-2470180966-3899876309-2637894779\\] "
293                 "Group \\[the-group-name\\] "
294                 "User \\[the-user-name\\]";
295
296         ret = regcomp(&regex, rs, 0);
297         assert_int_equal(0, ret);
298
299         ret = regexec(&regex, line, 0, NULL, 0);
300         assert_int_equal(0, ret);
301
302         regfree(&regex);
303         TALLOC_FREE(ctx);
304
305 }
306
307 /*
308  * test get_parsed_dns
309  * For this test we assume Valgrind or Address Sanitizer will detect any over
310  * runs. Also we don't care that the values are DN's only that the value in the
311  * element is copied to the parsed_dns.
312  */
313 static void test_get_parsed_dns(void **state)
314 {
315         struct ldb_message_element *el = NULL;
316         struct parsed_dn *dns = NULL;
317
318         TALLOC_CTX *ctx = talloc_new(NULL);
319
320         el = talloc_zero(ctx, struct ldb_message_element);
321
322         /*
323          * empty element, zero dns
324          */
325         dns = get_parsed_dns(ctx, el);
326         assert_null(dns);
327
328         /*
329          * one entry
330          */
331         el->num_values = 1;
332         el->values = talloc_zero_array(ctx, DATA_BLOB, 1);
333         el->values[0] = data_blob_string_const("The first value");
334
335         dns = get_parsed_dns(ctx, el);
336
337         assert_ptr_equal(el->values[0].data, dns[0].v->data);
338         assert_int_equal(el->values[0].length, dns[0].v->length);
339
340         TALLOC_FREE(dns);
341         TALLOC_FREE(el);
342
343
344         /*
345          * Multiple values
346          */
347         el = talloc_zero(ctx, struct ldb_message_element);
348         el->num_values = 2;
349         el->values = talloc_zero_array(ctx, DATA_BLOB, 2);
350         el->values[0] = data_blob_string_const("The first value");
351         el->values[0] = data_blob_string_const("The second value");
352
353         dns = get_parsed_dns(ctx, el);
354
355         assert_ptr_equal(el->values[0].data, dns[0].v->data);
356         assert_int_equal(el->values[0].length, dns[0].v->length);
357
358         assert_ptr_equal(el->values[1].data, dns[1].v->data);
359         assert_int_equal(el->values[1].length, dns[1].v->length);
360
361         TALLOC_FREE(ctx);
362 }
363
364 static void test_dn_compare(void **state)
365 {
366
367         struct ldb_context *ldb = NULL;
368         struct parsed_dn *a;
369         DATA_BLOB ab;
370
371         struct parsed_dn *b;
372         DATA_BLOB bb;
373
374         int res;
375
376         TALLOC_CTX *ctx = talloc_new(NULL);
377         const struct GUID *ZERO_GUID = talloc_zero(ctx, struct GUID);
378
379         ldb = ldb_init(ctx, NULL);
380         ldb_register_samba_handlers(ldb);
381
382
383         /*
384          * Identical binary DN's
385          */
386         ab = data_blob_string_const(
387                 "<GUID=fbee08fd-6f75-4bd4-af3f-e4f063a6379e>;"
388                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=org");
389         a = talloc_zero(ctx, struct parsed_dn);
390         a->v = &ab;
391
392         bb = data_blob_string_const(
393                 "<GUID=fbee08fd-6f75-4bd4-af3f-e4f063a6379e>;"
394                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=org");
395         b = talloc_zero(ctx, struct parsed_dn);
396         b->v = &bb;
397
398         res = dn_compare(ctx, ldb, a, b);
399         assert_int_equal(BINARY_EQUAL, res);
400         /*
401          * DN's should not have been parsed
402          */
403         assert_null(a->dsdb_dn);
404         assert_memory_equal(ZERO_GUID, &a->guid, sizeof(struct GUID));
405         assert_null(b->dsdb_dn);
406         assert_memory_equal(ZERO_GUID, &b->guid, sizeof(struct GUID));
407
408         TALLOC_FREE(a);
409         TALLOC_FREE(b);
410
411         /*
412          * differing binary DN's but equal GUID's
413          */
414         ab = data_blob_string_const(
415                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651e>;"
416                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=com");
417         a = talloc_zero(ctx, struct parsed_dn);
418         a->v = &ab;
419
420         bb = data_blob_string_const(
421                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651e>;"
422                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=org");
423         b = talloc_zero(ctx, struct parsed_dn);
424         b->v = &bb;
425
426         res = dn_compare(ctx, ldb, a, b);
427         assert_int_equal(EQUAL, res);
428         /*
429          * DN's should have been parsed
430          */
431         assert_non_null(a->dsdb_dn);
432         assert_memory_not_equal(ZERO_GUID, &a->guid, sizeof(struct GUID));
433         assert_non_null(b->dsdb_dn);
434         assert_memory_not_equal(ZERO_GUID, &b->guid, sizeof(struct GUID));
435
436         TALLOC_FREE(a);
437         TALLOC_FREE(b);
438
439         /*
440          * differing binary DN's but and second guid greater
441          */
442         ab = data_blob_string_const(
443                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651d>;"
444                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=com");
445         a = talloc_zero(ctx, struct parsed_dn);
446         a->v = &ab;
447
448         bb = data_blob_string_const(
449                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651e>;"
450                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=org");
451         b = talloc_zero(ctx, struct parsed_dn);
452         b->v = &bb;
453
454         res = dn_compare(ctx, ldb, a, b);
455         assert_int_equal(GREATER_THAN, res);
456         /*
457          * DN's should have been parsed
458          */
459         assert_non_null(a->dsdb_dn);
460         assert_memory_not_equal(ZERO_GUID, &a->guid, sizeof(struct GUID));
461         assert_non_null(b->dsdb_dn);
462         assert_memory_not_equal(ZERO_GUID, &b->guid, sizeof(struct GUID));
463
464         TALLOC_FREE(a);
465         TALLOC_FREE(b);
466
467         /*
468          * differing binary DN's but and second guid less
469          */
470         ab = data_blob_string_const(
471                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651d>;"
472                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=com");
473         a = talloc_zero(ctx, struct parsed_dn);
474         a->v = &ab;
475
476         bb = data_blob_string_const(
477                 "<GUID=efdc91e5-5a5a-493e-9606-166ed0c2651c>;"
478                 "OU=Domain Controllers,DC=ad,DC=testing,DC=samba,DC=org");
479         b = talloc_zero(ctx, struct parsed_dn);
480         b->v = &bb;
481
482         res = dn_compare(ctx, ldb, a, b);
483         assert_int_equal(LESS_THAN, res);
484         /*
485          * DN's should have been parsed
486          */
487         assert_non_null(a->dsdb_dn);
488         assert_memory_not_equal(ZERO_GUID, &a->guid, sizeof(struct GUID));
489         assert_non_null(b->dsdb_dn);
490         assert_memory_not_equal(ZERO_GUID, &b->guid, sizeof(struct GUID));
491
492         TALLOC_FREE(a);
493         TALLOC_FREE(b);
494
495         TALLOC_FREE(ctx);
496 }
497
498 static void test_get_primary_group_dn(void **state)
499 {
500
501         struct ldb_context *ldb = NULL;
502         struct ldb_module *module = NULL;
503         const uint32_t RID = 71;
504         struct dom_sid sid;
505         const char *SID = "S-1-5-21-2470180966-3899876309-2637894779";
506         const char *DN = "OU=Things,DC=ad,DC=testing,DC=samba,DC=org";
507         const char *dn;
508
509         TALLOC_CTX *ctx = talloc_new(NULL);
510
511         ldb = ldb_init(ctx, NULL);
512         ldb_register_samba_handlers(ldb);
513
514         module = talloc_zero(ctx, struct ldb_module);
515         module->ldb = ldb;
516
517         /*
518          * Pass an empty dom sid this will cause dom_sid_split_rid to fail;
519          * assign to sid.num_auths to suppress a valgrind warning.
520          */
521         sid.num_auths = 0;
522         dn = get_primary_group_dn(ctx, module, &sid, RID);
523         assert_null(dn);
524
525         /*
526          * A valid dom sid
527          */
528         assert_true(string_to_sid(&sid, SID));
529         g_dn = DN;
530         dn = get_primary_group_dn(ctx, module, &sid, RID);
531         assert_non_null(dn);
532         assert_string_equal(DN, dn);
533         assert_int_equal(LDB_SCOPE_BASE, g_scope);
534         assert_int_equal(0, g_dsdb_flags);
535         assert_null(g_attrs);
536         assert_null(g_exp_fmt);
537         assert_string_equal
538                 ("<SID=S-1-5-21-2470180966-3899876309-71>",
539                 ldb_dn_get_extended_linearized(ctx, g_basedn, 1));
540
541         /*
542          * Test dsdb search failure
543          */
544         g_status = LDB_ERR_NO_SUCH_OBJECT;
545         dn = get_primary_group_dn(ctx, module, &sid, RID);
546         assert_null(dn);
547
548         TALLOC_FREE(ldb);
549         TALLOC_FREE(ctx);
550 }
551
552 /*
553  * Mocking for audit_log_json to capture the called parameters
554  */
555 const char *audit_log_json_prefix = NULL;
556 struct json_object *audit_log_json_message = NULL;
557 int audit_log_json_debug_class = 0;
558 int audit_log_json_debug_level = 0;
559
560 static void audit_log_json_init(void)
561 {
562         audit_log_json_prefix = NULL;
563         audit_log_json_message = NULL;
564         audit_log_json_debug_class = 0;
565         audit_log_json_debug_level = 0;
566 }
567
568 void audit_log_json(
569         const char* prefix,
570         struct json_object* message,
571         int debug_class,
572         int debug_level)
573 {
574         audit_log_json_prefix = prefix;
575         audit_log_json_message = message;
576         audit_log_json_debug_class = debug_class;
577         audit_log_json_debug_level = debug_level;
578 }
579
580 /*
581  * Mocking for audit_message_send to capture the called parameters
582  */
583 struct imessaging_context *audit_message_send_msg_ctx = NULL;
584 const char *audit_message_send_server_name = NULL;
585 uint32_t audit_message_send_message_type = 0;
586 struct json_object *audit_message_send_message = NULL;
587
588 static void audit_message_send_init(void) {
589         audit_message_send_msg_ctx = NULL;
590         audit_message_send_server_name = NULL;
591         audit_message_send_message_type = 0;
592         audit_message_send_message = NULL;
593 }
594 void audit_message_send(
595         struct imessaging_context *msg_ctx,
596         const char *server_name,
597         uint32_t message_type,
598         struct json_object *message)
599 {
600         audit_message_send_msg_ctx = msg_ctx;
601         audit_message_send_server_name = server_name;
602         audit_message_send_message_type = message_type;
603         audit_message_send_message = message;
604 }
605
606 static void test_audit_group_json(void **state)
607 {
608         struct ldb_context *ldb = NULL;
609         struct ldb_module  *module = NULL;
610         struct ldb_request *req = NULL;
611
612         struct tsocket_address *ts = NULL;
613
614         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
615         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
616
617         struct GUID transaction_id;
618         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
619
620
621         struct json_object json;
622         json_t *audit = NULL;
623         json_t *v = NULL;
624         json_t *o = NULL;
625         time_t before;
626
627
628         TALLOC_CTX *ctx = talloc_new(NULL);
629
630         ldb = talloc_zero(ctx, struct ldb_context);
631
632         GUID_from_string(TRANSACTION, &transaction_id);
633
634         module = talloc_zero(ctx, struct ldb_module);
635         module->ldb = ldb;
636
637         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
638         ldb_set_opaque(ldb, "remoteAddress", ts);
639
640         add_session_data(ctx, ldb, SESSION, SID);
641
642         req = talloc_zero(ctx, struct ldb_request);
643         req->operation =  LDB_ADD;
644         add_transaction_id(req, TRANSACTION);
645
646         before = time(NULL);
647         json = audit_group_json(
648                 module,
649                 req,
650                 "the-action",
651                 "the-user-name",
652                 "the-group-name",
653                 LDB_ERR_OPERATIONS_ERROR);
654         assert_int_equal(3, json_object_size(json.root));
655
656         v = json_object_get(json.root, "type");
657         assert_non_null(v);
658         assert_string_equal("groupChange", json_string_value(v));
659
660         v = json_object_get(json.root, "timestamp");
661         assert_non_null(v);
662         assert_true(json_is_string(v));
663         check_timestamp(before, json_string_value(v));
664
665         audit = json_object_get(json.root, "groupChange");
666         assert_non_null(audit);
667         assert_true(json_is_object(audit));
668         assert_int_equal(10, json_object_size(audit));
669
670         o = json_object_get(audit, "version");
671         assert_non_null(o);
672         check_version(o, AUDIT_MAJOR, AUDIT_MINOR);
673
674         v = json_object_get(audit, "statusCode");
675         assert_non_null(v);
676         assert_true(json_is_integer(v));
677         assert_int_equal(LDB_ERR_OPERATIONS_ERROR, json_integer_value(v));
678
679         v = json_object_get(audit, "status");
680         assert_non_null(v);
681         assert_true(json_is_string(v));
682         assert_string_equal("Operations error", json_string_value(v));
683
684         v = json_object_get(audit, "user");
685         assert_non_null(v);
686         assert_true(json_is_string(v));
687         assert_string_equal("the-user-name", json_string_value(v));
688
689         v = json_object_get(audit, "group");
690         assert_non_null(v);
691         assert_true(json_is_string(v));
692         assert_string_equal("the-group-name", json_string_value(v));
693
694         v = json_object_get(audit, "action");
695         assert_non_null(v);
696         assert_true(json_is_string(v));
697         assert_string_equal("the-action", json_string_value(v));
698
699         json_free(&json);
700         TALLOC_FREE(ctx);
701
702 }
703
704 static void test_place_holder(void **state)
705 {
706         audit_log_json_init();
707         audit_log_hr_init();
708         audit_message_send_init();
709 }
710
711 /*
712  * Note: to run under valgrind us:
713  *       valgrind --suppressions=test_group_audit.valgrind bin/test_group_audit
714  *       This suppresses the errors generated because the ldb_modules are not
715  *       de-registered.
716  *
717  */
718 int main(void) {
719         const struct CMUnitTest tests[] = {
720                 cmocka_unit_test(test_audit_group_json),
721                 cmocka_unit_test(test_place_holder),
722                 cmocka_unit_test(test_get_transaction_id),
723                 cmocka_unit_test(test_audit_group_hr),
724                 cmocka_unit_test(test_get_parsed_dns),
725                 cmocka_unit_test(test_dn_compare),
726                 cmocka_unit_test(test_get_primary_group_dn),
727
728         };
729
730         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
731         return cmocka_run_group_tests(tests, NULL, NULL);
732 }