dsdb: Use customary variable names for the audit private context
[nivanova/samba-autobuild/.git] / source4 / dsdb / samdb / ldb_modules / tests / test_audit_log.c
1 /*
2    Unit tests for the dsdb audit logging code code in audit_log.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_audit_log_module_init(const char *version);
27 #include "../audit_log.c"
28
29 #include "lib/ldb/include/ldb_private.h"
30 #include <regex.h>
31
32 /*
33  * Test helper to check ISO 8601 timestamps for validity
34  */
35 static void check_timestamp(time_t before, const char* timestamp)
36 {
37         int rc;
38         int usec, tz;
39         char c[2];
40         struct tm tm;
41         time_t after;
42         time_t actual;
43
44
45         after = time(NULL);
46
47         /*
48          * Convert the ISO 8601 timestamp into a time_t
49          * Note for convenience we ignore the value of the microsecond
50          * part of the time stamp.
51          */
52         rc = sscanf(
53                 timestamp,
54                 "%4d-%2d-%2dT%2d:%2d:%2d.%6d%1c%4d",
55                 &tm.tm_year,
56                 &tm.tm_mon,
57                 &tm.tm_mday,
58                 &tm.tm_hour,
59                 &tm.tm_min,
60                 &tm.tm_sec,
61                 &usec,
62                 c,
63                 &tz);
64         assert_int_equal(9, rc);
65         tm.tm_year = tm.tm_year - 1900;
66         tm.tm_mon = tm.tm_mon - 1;
67         tm.tm_isdst = -1;
68         actual = mktime(&tm);
69
70         /*
71          * The timestamp should be before <= actual <= after
72          */
73         assert_true(difftime(actual, before) >= 0);
74         assert_true(difftime(after, actual) >= 0);
75 }
76
77 static void test_has_password_changed(void **state)
78 {
79         struct ldb_context *ldb = NULL;
80         struct ldb_message *msg = NULL;
81
82         TALLOC_CTX *ctx = talloc_new(NULL);
83
84         ldb = ldb_init(ctx, NULL);
85
86         /*
87          * Empty message
88          */
89         msg = ldb_msg_new(ldb);
90         assert_false(has_password_changed(msg));
91         TALLOC_FREE(msg);
92
93         /*
94          * No password attributes
95          */
96         msg = ldb_msg_new(ldb);
97         ldb_msg_add_string(msg, "attr01", "value01");
98         assert_false(has_password_changed(msg));
99         TALLOC_FREE(msg);
100
101         /*
102          * No password attributes >1 entries
103          */
104         msg = ldb_msg_new(ldb);
105         ldb_msg_add_string(msg, "attr01", "value01");
106         ldb_msg_add_string(msg, "attr02", "value03");
107         ldb_msg_add_string(msg, "attr03", "value03");
108         assert_false(has_password_changed(msg));
109         TALLOC_FREE(msg);
110
111         /*
112          *  userPassword set
113          */
114         msg = ldb_msg_new(ldb);
115         ldb_msg_add_string(msg, "userPassword", "value01");
116         assert_true(has_password_changed(msg));
117         TALLOC_FREE(msg);
118
119         /*
120          *  clearTextPassword set
121          */
122         msg = ldb_msg_new(ldb);
123         ldb_msg_add_string(msg, "clearTextPassword", "value01");
124         assert_true(has_password_changed(msg));
125         TALLOC_FREE(msg);
126
127         /*
128          *  unicodePwd set
129          */
130         msg = ldb_msg_new(ldb);
131         ldb_msg_add_string(msg, "unicodePwd", "value01");
132         assert_true(has_password_changed(msg));
133         TALLOC_FREE(msg);
134
135         /*
136          *  dBCSPwd set
137          */
138         msg = ldb_msg_new(ldb);
139         ldb_msg_add_string(msg, "dBCSPwd", "value01");
140         assert_true(has_password_changed(msg));
141         TALLOC_FREE(msg);
142
143         /*
144          *  All attributes set
145          */
146         msg = ldb_msg_new(ldb);
147         ldb_msg_add_string(msg, "userPassword", "value01");
148         ldb_msg_add_string(msg, "clearTextPassword", "value02");
149         ldb_msg_add_string(msg, "unicodePwd", "value03");
150         ldb_msg_add_string(msg, "dBCSPwd", "value04");
151         assert_true(has_password_changed(msg));
152         TALLOC_FREE(msg);
153
154         /*
155          *  first attribute is a password attribute
156          */
157         msg = ldb_msg_new(ldb);
158         ldb_msg_add_string(msg, "userPassword", "value01");
159         ldb_msg_add_string(msg, "attr02", "value02");
160         ldb_msg_add_string(msg, "attr03", "value03");
161         ldb_msg_add_string(msg, "attr04", "value04");
162         assert_true(has_password_changed(msg));
163         TALLOC_FREE(msg);
164
165         /*
166          *  last attribute is a password attribute
167          */
168         msg = ldb_msg_new(ldb);
169         ldb_msg_add_string(msg, "attr01", "value01");
170         ldb_msg_add_string(msg, "attr02", "value02");
171         ldb_msg_add_string(msg, "attr03", "value03");
172         ldb_msg_add_string(msg, "clearTextPassword", "value04");
173         assert_true(has_password_changed(msg));
174         TALLOC_FREE(msg);
175
176         /*
177          *  middle attribute is a password attribute
178          */
179         msg = ldb_msg_new(ldb);
180         ldb_msg_add_string(msg, "attr01", "value01");
181         ldb_msg_add_string(msg, "attr02", "value02");
182         ldb_msg_add_string(msg, "unicodePwd", "pwd");
183         ldb_msg_add_string(msg, "attr03", "value03");
184         ldb_msg_add_string(msg, "attr04", "value04");
185         assert_true(has_password_changed(msg));
186         TALLOC_FREE(msg);
187
188         TALLOC_FREE(ctx);
189 }
190
191 static void test_get_password_action(void **state)
192 {
193         struct ldb_context *ldb = NULL;
194         struct ldb_request *req = NULL;
195         struct ldb_reply *reply = NULL;
196         struct dsdb_control_password_acl_validation *pav = NULL;
197         int ret;
198
199         TALLOC_CTX *ctx = talloc_new(NULL);
200         ldb = ldb_init(ctx, NULL);
201
202         /*
203          * Add request, will always be a reset
204          */
205         ldb_build_add_req(&req, ldb, ctx, NULL, NULL, NULL, NULL, NULL);
206         reply = talloc_zero(ctx, struct ldb_reply);
207         assert_string_equal("Reset", get_password_action(req, reply));
208         TALLOC_FREE(req);
209         TALLOC_FREE(reply);
210
211         /*
212          * No password control acl, expect "Reset"
213          */
214         ldb_build_mod_req(&req, ldb, ctx, NULL, NULL, NULL, NULL, NULL);
215         reply = talloc_zero(ctx, struct ldb_reply);
216         assert_string_equal("Reset", get_password_action(req, reply));
217         TALLOC_FREE(req);
218         TALLOC_FREE(reply);
219
220         /*
221          * dsdb_control_password_acl_validation reset = false, expect "Change"
222          */
223         ret = ldb_build_mod_req(&req, ldb, ctx, NULL, NULL, NULL, NULL, NULL);
224         assert_int_equal(ret, LDB_SUCCESS);
225         reply = talloc_zero(ctx, struct ldb_reply);
226         pav = talloc_zero(req, struct dsdb_control_password_acl_validation);
227
228         ldb_reply_add_control(
229                 reply,
230                 DSDB_CONTROL_PASSWORD_ACL_VALIDATION_OID,
231                 false,
232                 pav);
233         assert_string_equal("Change", get_password_action(req, reply));
234         TALLOC_FREE(req);
235         TALLOC_FREE(reply);
236
237         /*
238          * dsdb_control_password_acl_validation reset = true, expect "Reset"
239          */
240         ldb_build_mod_req(&req, ldb, ctx, NULL, NULL, NULL, NULL, NULL);
241         reply = talloc_zero(ctx, struct ldb_reply);
242         pav = talloc_zero(req, struct dsdb_control_password_acl_validation);
243         pav->pwd_reset = true;
244
245         ldb_reply_add_control(
246                 reply,
247                 DSDB_CONTROL_PASSWORD_ACL_VALIDATION_OID,
248                 false,
249                 pav);
250         assert_string_equal("Reset", get_password_action(req, reply));
251         TALLOC_FREE(req);
252         TALLOC_FREE(reply);
253
254         TALLOC_FREE(ctx);
255 }
256
257 /*
258  * Test helper to validate a version object.
259  */
260 static void check_version(struct json_t *version, int major, int minor)
261 {
262         struct json_t *v = NULL;
263
264         assert_true(json_is_object(version));
265         assert_int_equal(2, json_object_size(version));
266
267         v = json_object_get(version, "major");
268         assert_non_null(v);
269         assert_int_equal(major, json_integer_value(v));
270
271         v = json_object_get(version, "minor");
272         assert_non_null(v);
273         assert_int_equal(minor, json_integer_value(v));
274 }
275
276 /*
277  * minimal unit test of operation_json, that ensures that all the expected
278  * attributes and objects are in the json object.
279  */
280 static void test_operation_json_empty(void **state)
281 {
282         struct ldb_context *ldb = NULL;
283         struct ldb_module  *module = NULL;
284         struct ldb_request *req = NULL;
285         struct ldb_reply *reply = NULL;
286         struct audit_private *audit_private = NULL;
287
288         struct json_object json;
289         json_t *audit = NULL;
290         json_t *v = NULL;
291         json_t *o = NULL;
292         time_t before;
293
294
295         TALLOC_CTX *ctx = talloc_new(NULL);
296
297         ldb = ldb_init(ctx, NULL);
298         audit_private = talloc_zero(ctx, struct audit_private);
299
300         module = talloc_zero(ctx, struct ldb_module);
301         module->ldb = ldb;
302         ldb_module_set_private(module, audit_private);
303
304         req = talloc_zero(ctx, struct ldb_request);
305         reply = talloc_zero(ctx, struct ldb_reply);
306         reply->error = LDB_SUCCESS;
307
308         before = time(NULL);
309         json = operation_json(module, req, reply);
310         assert_int_equal(3, json_object_size(json.root));
311
312
313         v = json_object_get(json.root, "type");
314         assert_non_null(v);
315         assert_string_equal("dsdbChange", json_string_value(v));
316
317         v = json_object_get(json.root, "timestamp");
318         assert_non_null(v);
319         assert_true(json_is_string(v));
320         check_timestamp(before, json_string_value(v));
321
322         audit = json_object_get(json.root, "dsdbChange");
323         assert_non_null(audit);
324         assert_true(json_is_object(audit));
325         assert_int_equal(10, json_object_size(audit));
326
327         o = json_object_get(audit, "version");
328         assert_non_null(o);
329         check_version(o, OPERATION_MAJOR, OPERATION_MINOR);
330
331         v = json_object_get(audit, "statusCode");
332         assert_non_null(v);
333         assert_true(json_is_integer(v));
334         assert_int_equal(LDB_SUCCESS, json_integer_value(v));
335
336         v = json_object_get(audit, "status");
337         assert_non_null(v);
338         assert_true(json_is_string(v));
339         assert_string_equal("Success", json_string_value(v));
340
341         v = json_object_get(audit, "operation");
342         assert_non_null(v);
343         assert_true(json_is_string(v));
344         /*
345          * Search operation constant is zero
346          */
347         assert_string_equal("Search", json_string_value(v));
348
349         v = json_object_get(audit, "remoteAddress");
350         assert_non_null(v);
351         assert_true(json_is_null(v));
352
353         v = json_object_get(audit, "userSid");
354         assert_non_null(v);
355         assert_true(json_is_null(v));
356
357         v = json_object_get(audit, "performedAsSystem");
358         assert_non_null(v);
359         assert_true(json_is_boolean(v));
360         assert_true(json_is_false(v));
361
362
363         v = json_object_get(audit, "dn");
364         assert_non_null(v);
365         assert_true(json_is_null(v));
366
367         v = json_object_get(audit, "transactionId");
368         assert_non_null(v);
369         assert_true(json_is_string(v));
370         assert_string_equal(
371                 "00000000-0000-0000-0000-000000000000",
372                 json_string_value(v));
373
374         v = json_object_get(audit, "sessionId");
375         assert_non_null(v);
376         assert_true(json_is_null(v));
377
378         json_free(&json);
379         TALLOC_FREE(ctx);
380
381 }
382
383 /*
384  * unit test of operation_json, that ensures that all the expected
385  * attributes and objects are in the json object.
386  */
387 static void test_operation_json(void **state)
388 {
389         struct ldb_context *ldb = NULL;
390         struct ldb_module  *module = NULL;
391         struct ldb_request *req = NULL;
392         struct ldb_reply *reply = NULL;
393         struct audit_private *audit_private = NULL;
394
395         struct tsocket_address *ts = NULL;
396
397         struct auth_session_info *sess = NULL;
398         struct security_token *token = NULL;
399         struct dom_sid sid;
400         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
401         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
402         struct GUID session_id;
403
404         struct GUID transaction_id;
405         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
406
407         struct ldb_dn *dn = NULL;
408         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
409
410         struct ldb_message *msg = NULL;
411
412         struct json_object json;
413         json_t *audit = NULL;
414         json_t *v = NULL;
415         json_t *o = NULL;
416         json_t *a = NULL;
417         json_t *b = NULL;
418         json_t *c = NULL;
419         json_t *d = NULL;
420         json_t *e = NULL;
421         json_t *f = NULL;
422         json_t *g = NULL;
423         time_t before;
424
425
426         TALLOC_CTX *ctx = talloc_new(NULL);
427
428         ldb = ldb_init(ctx, NULL);
429
430         audit_private = talloc_zero(ctx, struct audit_private);
431         GUID_from_string(TRANSACTION, &transaction_id);
432         audit_private->transaction_guid = transaction_id;
433
434         module = talloc_zero(ctx, struct ldb_module);
435         module->ldb = ldb;
436         ldb_module_set_private(module, audit_private);
437
438         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
439         ldb_set_opaque(ldb, "remoteAddress", ts);
440
441         sess = talloc_zero(ctx, struct auth_session_info);
442         token = talloc_zero(ctx, struct security_token);
443         string_to_sid(&sid, SID);
444         token->num_sids = 1;
445         token->sids = &sid;
446         sess->security_token = token;
447         GUID_from_string(SESSION, &session_id);
448         sess->unique_session_token = session_id;
449         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
450
451         msg = talloc_zero(ctx, struct ldb_message);
452         dn = ldb_dn_new(ctx, ldb, DN);
453         msg->dn = dn;
454         ldb_msg_add_string(msg, "attribute", "the-value");
455
456         req = talloc_zero(ctx, struct ldb_request);
457         req->operation =  LDB_ADD;
458         req->op.add.message = msg;
459
460         reply = talloc_zero(ctx, struct ldb_reply);
461         reply->error = LDB_ERR_OPERATIONS_ERROR;
462
463         before = time(NULL);
464         json = operation_json(module, req, reply);
465         assert_int_equal(3, json_object_size(json.root));
466
467         v = json_object_get(json.root, "type");
468         assert_non_null(v);
469         assert_string_equal("dsdbChange", json_string_value(v));
470
471         v = json_object_get(json.root, "timestamp");
472         assert_non_null(v);
473         assert_true(json_is_string(v));
474         check_timestamp(before, json_string_value(v));
475
476         audit = json_object_get(json.root, "dsdbChange");
477         assert_non_null(audit);
478         assert_true(json_is_object(audit));
479         assert_int_equal(11, json_object_size(audit));
480
481         o = json_object_get(audit, "version");
482         assert_non_null(o);
483         check_version(o, OPERATION_MAJOR, OPERATION_MINOR);
484
485         v = json_object_get(audit, "statusCode");
486         assert_non_null(v);
487         assert_true(json_is_integer(v));
488         assert_int_equal(LDB_ERR_OPERATIONS_ERROR, json_integer_value(v));
489
490         v = json_object_get(audit, "status");
491         assert_non_null(v);
492         assert_true(json_is_string(v));
493         assert_string_equal("Operations error", json_string_value(v));
494
495         v = json_object_get(audit, "operation");
496         assert_non_null(v);
497         assert_true(json_is_string(v));
498         assert_string_equal("Add", json_string_value(v));
499
500         v = json_object_get(audit, "remoteAddress");
501         assert_non_null(v);
502         assert_true(json_is_string(v));
503         assert_string_equal("ipv4:127.0.0.1:0", json_string_value(v));
504
505         v = json_object_get(audit, "userSid");
506         assert_non_null(v);
507         assert_true(json_is_string(v));
508         assert_string_equal(SID, json_string_value(v));
509
510         v = json_object_get(audit, "performedAsSystem");
511         assert_non_null(v);
512         assert_true(json_is_boolean(v));
513         assert_true(json_is_false(v));
514
515         v = json_object_get(audit, "dn");
516         assert_non_null(v);
517         assert_true(json_is_string(v));
518         assert_string_equal(DN, json_string_value(v));
519
520         v = json_object_get(audit, "transactionId");
521         assert_non_null(v);
522         assert_true(json_is_string(v));
523         assert_string_equal(TRANSACTION, json_string_value(v));
524
525         v = json_object_get(audit, "sessionId");
526         assert_non_null(v);
527         assert_true(json_is_string(v));
528         assert_string_equal(SESSION, json_string_value(v));
529
530         o = json_object_get(audit, "attributes");
531         assert_non_null(v);
532         assert_true(json_is_object(o));
533         assert_int_equal(1, json_object_size(o));
534
535         a = json_object_get(o, "attribute");
536         assert_non_null(a);
537         assert_true(json_is_object(a));
538
539         b = json_object_get(a, "actions");
540         assert_non_null(b);
541         assert_true(json_is_array(b));
542         assert_int_equal(1, json_array_size(b));
543
544         c = json_array_get(b, 0);
545         assert_non_null(c);
546         assert_true(json_is_object(c));
547
548         d = json_object_get(c, "action");
549         assert_non_null(d);
550         assert_true(json_is_string(d));
551         assert_string_equal("add", json_string_value(d));
552
553         e = json_object_get(c, "values");
554         assert_non_null(b);
555         assert_true(json_is_array(e));
556         assert_int_equal(1, json_array_size(e));
557
558         f = json_array_get(e, 0);
559         assert_non_null(f);
560         assert_true(json_is_object(f));
561         assert_int_equal(1, json_object_size(f));
562
563         g = json_object_get(f, "value");
564         assert_non_null(g);
565         assert_true(json_is_string(g));
566         assert_string_equal("the-value", json_string_value(g));
567
568         json_free(&json);
569         TALLOC_FREE(ctx);
570
571 }
572
573 /*
574  * unit test of operation_json, that ensures that all the expected
575  * attributes and objects are in the json object.
576  * In this case for an operation performed as the system user.
577  */
578 static void test_as_system_operation_json(void **state)
579 {
580         struct ldb_context *ldb = NULL;
581         struct ldb_module  *module = NULL;
582         struct ldb_request *req = NULL;
583         struct ldb_reply *reply = NULL;
584         struct audit_private *audit_private = NULL;
585
586         struct tsocket_address *ts = NULL;
587
588         struct auth_session_info *sess = NULL;
589         struct auth_session_info *sys_sess = NULL;
590         struct security_token *token = NULL;
591         struct security_token *sys_token = NULL;
592         struct dom_sid sid;
593         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
594         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
595         const char * const SYS_SESSION = "7130cb06-2062-6a1b-409e-3514c26b1998";
596         struct GUID session_id;
597         struct GUID sys_session_id;
598
599         struct GUID transaction_id;
600         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
601
602         struct ldb_dn *dn = NULL;
603         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
604
605         struct ldb_message *msg = NULL;
606
607         struct json_object json;
608         json_t *audit = NULL;
609         json_t *v = NULL;
610         json_t *o = NULL;
611         json_t *a = NULL;
612         json_t *b = NULL;
613         json_t *c = NULL;
614         json_t *d = NULL;
615         json_t *e = NULL;
616         json_t *f = NULL;
617         json_t *g = NULL;
618         time_t before;
619
620
621         TALLOC_CTX *ctx = talloc_new(NULL);
622
623         ldb = ldb_init(ctx, NULL);
624
625         audit_private = talloc_zero(ctx, struct audit_private);
626         GUID_from_string(TRANSACTION, &transaction_id);
627         audit_private->transaction_guid = transaction_id;
628
629         module = talloc_zero(ctx, struct ldb_module);
630         module->ldb = ldb;
631         ldb_module_set_private(module, audit_private);
632
633         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
634         ldb_set_opaque(ldb, "remoteAddress", ts);
635
636         sess = talloc_zero(ctx, struct auth_session_info);
637         token = talloc_zero(ctx, struct security_token);
638         string_to_sid(&sid, SID);
639         token->num_sids = 1;
640         token->sids = &sid;
641         sess->security_token = token;
642         GUID_from_string(SESSION, &session_id);
643         sess->unique_session_token = session_id;
644         ldb_set_opaque(ldb, DSDB_NETWORK_SESSION_INFO, sess);
645
646         sys_sess = talloc_zero(ctx, struct auth_session_info);
647         sys_token = talloc_zero(ctx, struct security_token);
648         sys_token->num_sids = 1;
649         sys_token->sids = discard_const(&global_sid_System);
650         sys_sess->security_token = sys_token;
651         GUID_from_string(SYS_SESSION, &sys_session_id);
652         sess->unique_session_token = sys_session_id;
653         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sys_sess);
654
655         msg = talloc_zero(ctx, struct ldb_message);
656         dn = ldb_dn_new(ctx, ldb, DN);
657         msg->dn = dn;
658         ldb_msg_add_string(msg, "attribute", "the-value");
659
660         req = talloc_zero(ctx, struct ldb_request);
661         req->operation =  LDB_ADD;
662         req->op.add.message = msg;
663
664         reply = talloc_zero(ctx, struct ldb_reply);
665         reply->error = LDB_ERR_OPERATIONS_ERROR;
666
667         before = time(NULL);
668         json = operation_json(module, req, reply);
669         assert_int_equal(3, json_object_size(json.root));
670
671         v = json_object_get(json.root, "type");
672         assert_non_null(v);
673         assert_string_equal("dsdbChange", json_string_value(v));
674
675         v = json_object_get(json.root, "timestamp");
676         assert_non_null(v);
677         assert_true(json_is_string(v));
678         check_timestamp(before, json_string_value(v));
679
680         audit = json_object_get(json.root, "dsdbChange");
681         assert_non_null(audit);
682         assert_true(json_is_object(audit));
683         assert_int_equal(11, json_object_size(audit));
684
685         o = json_object_get(audit, "version");
686         assert_non_null(o);
687         check_version(o, OPERATION_MAJOR, OPERATION_MINOR);
688
689         v = json_object_get(audit, "statusCode");
690         assert_non_null(v);
691         assert_true(json_is_integer(v));
692         assert_int_equal(LDB_ERR_OPERATIONS_ERROR, json_integer_value(v));
693
694         v = json_object_get(audit, "status");
695         assert_non_null(v);
696         assert_true(json_is_string(v));
697         assert_string_equal("Operations error", json_string_value(v));
698
699         v = json_object_get(audit, "operation");
700         assert_non_null(v);
701         assert_true(json_is_string(v));
702         assert_string_equal("Add", json_string_value(v));
703
704         v = json_object_get(audit, "remoteAddress");
705         assert_non_null(v);
706         assert_true(json_is_string(v));
707         assert_string_equal("ipv4:127.0.0.1:0", json_string_value(v));
708
709         v = json_object_get(audit, "userSid");
710         assert_non_null(v);
711         assert_true(json_is_string(v));
712         assert_string_equal(SID, json_string_value(v));
713
714         v = json_object_get(audit, "performedAsSystem");
715         assert_non_null(v);
716         assert_true(json_is_boolean(v));
717         assert_true(json_is_true(v));
718
719         v = json_object_get(audit, "dn");
720         assert_non_null(v);
721         assert_true(json_is_string(v));
722         assert_string_equal(DN, json_string_value(v));
723
724         v = json_object_get(audit, "transactionId");
725         assert_non_null(v);
726         assert_true(json_is_string(v));
727         assert_string_equal(TRANSACTION, json_string_value(v));
728
729         v = json_object_get(audit, "sessionId");
730         assert_non_null(v);
731         assert_true(json_is_string(v));
732         assert_string_equal(SYS_SESSION, json_string_value(v));
733
734         o = json_object_get(audit, "attributes");
735         assert_non_null(v);
736         assert_true(json_is_object(o));
737         assert_int_equal(1, json_object_size(o));
738
739         a = json_object_get(o, "attribute");
740         assert_non_null(a);
741         assert_true(json_is_object(a));
742
743         b = json_object_get(a, "actions");
744         assert_non_null(b);
745         assert_true(json_is_array(b));
746         assert_int_equal(1, json_array_size(b));
747
748         c = json_array_get(b, 0);
749         assert_non_null(c);
750         assert_true(json_is_object(c));
751
752         d = json_object_get(c, "action");
753         assert_non_null(d);
754         assert_true(json_is_string(d));
755         assert_string_equal("add", json_string_value(d));
756
757         e = json_object_get(c, "values");
758         assert_non_null(b);
759         assert_true(json_is_array(e));
760         assert_int_equal(1, json_array_size(e));
761
762         f = json_array_get(e, 0);
763         assert_non_null(f);
764         assert_true(json_is_object(f));
765         assert_int_equal(1, json_object_size(f));
766
767         g = json_object_get(f, "value");
768         assert_non_null(g);
769         assert_true(json_is_string(g));
770         assert_string_equal("the-value", json_string_value(g));
771
772         json_free(&json);
773         TALLOC_FREE(ctx);
774
775 }
776
777 /*
778  * minimal unit test of password_change_json, that ensures that all the expected
779  * attributes and objects are in the json object.
780  */
781 static void test_password_change_json_empty(void **state)
782 {
783         struct ldb_context *ldb = NULL;
784         struct ldb_module  *module = NULL;
785         struct ldb_request *req = NULL;
786         struct ldb_reply *reply = NULL;
787         struct audit_private *audit_private = NULL;
788
789         struct json_object json;
790         json_t *audit = NULL;
791         json_t *v = NULL;
792         json_t *o = NULL;
793         time_t before;
794
795
796         TALLOC_CTX *ctx = talloc_new(NULL);
797
798         ldb = ldb_init(ctx, NULL);
799         audit_private = talloc_zero(ctx, struct audit_private);
800
801         module = talloc_zero(ctx, struct ldb_module);
802         module->ldb = ldb;
803         ldb_module_set_private(module, audit_private);
804
805         req = talloc_zero(ctx, struct ldb_request);
806         reply = talloc_zero(ctx, struct ldb_reply);
807         reply->error = LDB_SUCCESS;
808
809         before = time(NULL);
810         json = password_change_json(module, req, reply);
811         assert_int_equal(3, json_object_size(json.root));
812
813
814         v = json_object_get(json.root, "type");
815         assert_non_null(v);
816         assert_string_equal("passwordChange", json_string_value(v));
817
818         v = json_object_get(json.root, "timestamp");
819         assert_non_null(v);
820         assert_true(json_is_string(v));
821         check_timestamp(before, json_string_value(v));
822
823         audit = json_object_get(json.root, "passwordChange");
824         assert_non_null(audit);
825         assert_true(json_is_object(audit));
826         assert_int_equal(9, json_object_size(audit));
827
828         o = json_object_get(audit, "version");
829         assert_non_null(o);
830
831         v = json_object_get(audit, "statusCode");
832         assert_non_null(v);
833
834         v = json_object_get(audit, "status");
835         assert_non_null(v);
836
837         v = json_object_get(audit, "remoteAddress");
838         assert_non_null(v);
839
840         v = json_object_get(audit, "userSid");
841         assert_non_null(v);
842
843         v = json_object_get(audit, "dn");
844         assert_non_null(v);
845
846         v = json_object_get(audit, "transactionId");
847         assert_non_null(v);
848
849         v = json_object_get(audit, "sessionId");
850         assert_non_null(v);
851
852         v = json_object_get(audit, "action");
853         assert_non_null(v);
854
855         json_free(&json);
856         TALLOC_FREE(ctx);
857
858 }
859
860 /*
861  * minimal unit test of password_change_json, that ensures that all the expected
862  * attributes and objects are in the json object.
863  */
864 static void test_password_change_json(void **state)
865 {
866         struct ldb_context *ldb = NULL;
867         struct ldb_module  *module = NULL;
868         struct ldb_request *req = NULL;
869         struct ldb_reply *reply = NULL;
870         struct audit_private *audit_private = NULL;
871
872         struct tsocket_address *ts = NULL;
873
874         struct auth_session_info *sess = NULL;
875         struct security_token *token = NULL;
876         struct dom_sid sid;
877         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
878         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
879         struct GUID session_id;
880
881         struct GUID transaction_id;
882         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
883
884         struct ldb_dn *dn = NULL;
885         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
886
887         struct ldb_message *msg = NULL;
888
889         struct json_object json;
890         json_t *audit = NULL;
891         json_t *v = NULL;
892         json_t *o = NULL;
893         time_t before;
894
895         TALLOC_CTX *ctx = talloc_new(NULL);
896
897         ldb = ldb_init(ctx, NULL);
898
899         audit_private = talloc_zero(ctx, struct audit_private);
900         GUID_from_string(TRANSACTION, &transaction_id);
901         audit_private->transaction_guid = transaction_id;
902
903         module = talloc_zero(ctx, struct ldb_module);
904         module->ldb = ldb;
905         ldb_module_set_private(module, audit_private);
906
907         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
908         ldb_set_opaque(ldb, "remoteAddress", ts);
909
910         sess = talloc_zero(ctx, struct auth_session_info);
911         token = talloc_zero(ctx, struct security_token);
912         string_to_sid(&sid, SID);
913         token->num_sids = 1;
914         token->sids = &sid;
915         sess->security_token = token;
916         GUID_from_string(SESSION, &session_id);
917         sess->unique_session_token = session_id;
918         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
919
920         msg = talloc_zero(ctx, struct ldb_message);
921         dn = ldb_dn_new(ctx, ldb, DN);
922         msg->dn = dn;
923         ldb_msg_add_string(msg, "planTextPassword", "super-secret");
924
925         req = talloc_zero(ctx, struct ldb_request);
926         req->operation =  LDB_ADD;
927         req->op.add.message = msg;
928         reply = talloc_zero(ctx, struct ldb_reply);
929         reply->error = LDB_SUCCESS;
930
931         before = time(NULL);
932         json = password_change_json(module, req, reply);
933         assert_int_equal(3, json_object_size(json.root));
934
935
936         v = json_object_get(json.root, "type");
937         assert_non_null(v);
938         assert_string_equal("passwordChange", json_string_value(v));
939
940         v = json_object_get(json.root, "timestamp");
941         assert_non_null(v);
942         assert_true(json_is_string(v));
943         check_timestamp(before, json_string_value(v));
944
945         audit = json_object_get(json.root, "passwordChange");
946         assert_non_null(audit);
947         assert_true(json_is_object(audit));
948         assert_int_equal(9, json_object_size(audit));
949
950         o = json_object_get(audit, "version");
951         assert_non_null(o);
952         check_version(o, PASSWORD_MAJOR,PASSWORD_MINOR);
953
954         v = json_object_get(audit, "statusCode");
955         assert_non_null(v);
956         assert_true(json_is_integer(v));
957         assert_int_equal(LDB_SUCCESS, json_integer_value(v));
958
959         v = json_object_get(audit, "status");
960         assert_non_null(v);
961         assert_true(json_is_string(v));
962         assert_string_equal("Success", json_string_value(v));
963
964         v = json_object_get(audit, "remoteAddress");
965         assert_non_null(v);
966         assert_true(json_is_string(v));
967         assert_string_equal("ipv4:127.0.0.1:0", json_string_value(v));
968
969         v = json_object_get(audit, "userSid");
970         assert_non_null(v);
971         assert_true(json_is_string(v));
972         assert_string_equal(SID, json_string_value(v));
973
974         v = json_object_get(audit, "dn");
975         assert_non_null(v);
976         assert_true(json_is_string(v));
977         assert_string_equal(DN, json_string_value(v));
978
979         v = json_object_get(audit, "transactionId");
980         assert_non_null(v);
981         assert_true(json_is_string(v));
982         assert_string_equal(TRANSACTION, json_string_value(v));
983
984         v = json_object_get(audit, "sessionId");
985         assert_non_null(v);
986         assert_true(json_is_string(v));
987         assert_string_equal(SESSION, json_string_value(v));
988
989         v = json_object_get(audit, "action");
990         assert_non_null(v);
991         assert_true(json_is_string(v));
992         assert_string_equal("Reset", json_string_value(v));
993
994         json_free(&json);
995         TALLOC_FREE(ctx);
996
997 }
998
999
1000 /*
1001  * minimal unit test of transaction_json, that ensures that all the expected
1002  * attributes and objects are in the json object.
1003  */
1004 static void test_transaction_json(void **state)
1005 {
1006
1007         struct GUID guid;
1008         const char * const GUID = "7130cb06-2062-6a1b-409e-3514c26b1773";
1009
1010         struct json_object json;
1011         json_t *audit = NULL;
1012         json_t *v = NULL;
1013         json_t *o = NULL;
1014         time_t before;
1015
1016         GUID_from_string(GUID, &guid);
1017
1018         before = time(NULL);
1019         json = transaction_json("delete", &guid, 10000099);
1020
1021         assert_int_equal(3, json_object_size(json.root));
1022
1023
1024         v = json_object_get(json.root, "type");
1025         assert_non_null(v);
1026         assert_string_equal("dsdbTransaction", json_string_value(v));
1027
1028         v = json_object_get(json.root, "timestamp");
1029         assert_non_null(v);
1030         assert_true(json_is_string(v));
1031         check_timestamp(before, json_string_value(v));
1032
1033         audit = json_object_get(json.root, "dsdbTransaction");
1034         assert_non_null(audit);
1035         assert_true(json_is_object(audit));
1036         assert_int_equal(4, json_object_size(audit));
1037
1038         o = json_object_get(audit, "version");
1039         assert_non_null(o);
1040         check_version(o, TRANSACTION_MAJOR, TRANSACTION_MINOR);
1041
1042         v = json_object_get(audit, "transactionId");
1043         assert_non_null(v);
1044         assert_true(json_is_string(v));
1045         assert_string_equal(GUID, json_string_value(v));
1046
1047         v = json_object_get(audit, "action");
1048         assert_non_null(v);
1049         assert_true(json_is_string(v));
1050         assert_string_equal("delete", json_string_value(v));
1051
1052         v = json_object_get(audit, "duration");
1053         assert_non_null(v);
1054         assert_true(json_is_integer(v));
1055         assert_int_equal(10000099, json_integer_value(v));
1056
1057         json_free(&json);
1058
1059 }
1060
1061 /*
1062  * minimal unit test of commit_failure_json, that ensures that all the
1063  * expected attributes and objects are in the json object.
1064  */
1065 static void test_commit_failure_json(void **state)
1066 {
1067
1068         struct GUID guid;
1069         const char * const GUID = "7130cb06-2062-6a1b-409e-3514c26b1773";
1070
1071         struct json_object json;
1072         json_t *audit = NULL;
1073         json_t *v = NULL;
1074         json_t *o = NULL;
1075         time_t before;
1076
1077         GUID_from_string(GUID, &guid);
1078
1079         before = time(NULL);
1080         json = commit_failure_json(
1081                 "prepare",
1082                 987876,
1083                 LDB_ERR_OPERATIONS_ERROR,
1084                 "because",
1085                 &guid);
1086
1087         assert_int_equal(3, json_object_size(json.root));
1088
1089
1090         v = json_object_get(json.root, "type");
1091         assert_non_null(v);
1092         assert_string_equal("dsdbTransaction", json_string_value(v));
1093
1094         v = json_object_get(json.root, "timestamp");
1095         assert_non_null(v);
1096         assert_true(json_is_string(v));
1097         check_timestamp(before, json_string_value(v));
1098
1099         audit = json_object_get(json.root, "dsdbTransaction");
1100         assert_non_null(audit);
1101         assert_true(json_is_object(audit));
1102         assert_int_equal(7, json_object_size(audit));
1103
1104         o = json_object_get(audit, "version");
1105         assert_non_null(o);
1106         check_version(o, TRANSACTION_MAJOR, TRANSACTION_MINOR);
1107
1108         v = json_object_get(audit, "transactionId");
1109         assert_non_null(v);
1110         assert_true(json_is_string(v));
1111         assert_string_equal(GUID, json_string_value(v));
1112
1113         v = json_object_get(audit, "action");
1114         assert_non_null(v);
1115         assert_true(json_is_string(v));
1116         assert_string_equal("prepare", json_string_value(v));
1117
1118         v = json_object_get(audit, "statusCode");
1119         assert_non_null(v);
1120         assert_true(json_is_integer(v));
1121         assert_int_equal(LDB_ERR_OPERATIONS_ERROR, json_integer_value(v));
1122
1123         v = json_object_get(audit, "status");
1124         assert_non_null(v);
1125         assert_true(json_is_string(v));
1126         assert_string_equal("Operations error", json_string_value(v));
1127         v = json_object_get(audit, "status");
1128         assert_non_null(v);
1129
1130         v = json_object_get(audit, "reason");
1131         assert_non_null(v);
1132         assert_true(json_is_string(v));
1133         assert_string_equal("because", json_string_value(v));
1134
1135         v = json_object_get(audit, "duration");
1136         assert_non_null(v);
1137         assert_true(json_is_integer(v));
1138         assert_int_equal(987876, json_integer_value(v));
1139
1140         json_free(&json);
1141
1142 }
1143
1144 /*
1145  * minimal unit test of replicated_update_json, that ensures that all the
1146  * expected attributes and objects are in the json object.
1147  */
1148 static void test_replicated_update_json_empty(void **state)
1149 {
1150         struct ldb_context *ldb = NULL;
1151         struct ldb_module  *module = NULL;
1152         struct ldb_request *req = NULL;
1153         struct ldb_reply *reply = NULL;
1154         struct audit_private *audit_private = NULL;
1155         struct dsdb_extended_replicated_objects *ro = NULL;
1156         struct repsFromTo1 *source_dsa = NULL;
1157
1158         struct json_object json;
1159         json_t *audit = NULL;
1160         json_t *v = NULL;
1161         json_t *o = NULL;
1162         time_t before;
1163
1164
1165         TALLOC_CTX *ctx = talloc_new(NULL);
1166
1167         ldb = ldb_init(ctx, NULL);
1168         audit_private = talloc_zero(ctx, struct audit_private);
1169
1170         module = talloc_zero(ctx, struct ldb_module);
1171         module->ldb = ldb;
1172         ldb_module_set_private(module, audit_private);
1173
1174         source_dsa = talloc_zero(ctx, struct repsFromTo1);
1175         ro = talloc_zero(ctx, struct dsdb_extended_replicated_objects);
1176         ro->source_dsa = source_dsa;
1177         req = talloc_zero(ctx, struct ldb_request);
1178         req->op.extended.data = ro;
1179         req->operation = LDB_EXTENDED;
1180         reply = talloc_zero(ctx, struct ldb_reply);
1181         reply->error = LDB_SUCCESS;
1182
1183         before = time(NULL);
1184         json = replicated_update_json(module, req, reply);
1185         assert_int_equal(3, json_object_size(json.root));
1186
1187
1188         v = json_object_get(json.root, "type");
1189         assert_non_null(v);
1190         assert_string_equal("replicatedUpdate", json_string_value(v));
1191
1192         v = json_object_get(json.root, "timestamp");
1193         assert_non_null(v);
1194         assert_true(json_is_string(v));
1195         check_timestamp(before, json_string_value(v));
1196
1197         audit = json_object_get(json.root, "replicatedUpdate");
1198         assert_non_null(audit);
1199         assert_true(json_is_object(audit));
1200         assert_int_equal(11, json_object_size(audit));
1201
1202         o = json_object_get(audit, "version");
1203         assert_non_null(o);
1204         check_version(o, REPLICATION_MAJOR, REPLICATION_MINOR);
1205
1206         v = json_object_get(audit, "statusCode");
1207         assert_non_null(v);
1208         assert_true(json_is_integer(v));
1209         assert_int_equal(LDB_SUCCESS, json_integer_value(v));
1210
1211         v = json_object_get(audit, "status");
1212         assert_non_null(v);
1213         assert_true(json_is_string(v));
1214         assert_string_equal("Success", json_string_value(v));
1215
1216         v = json_object_get(audit, "transactionId");
1217         assert_non_null(v);
1218         assert_true(json_is_string(v));
1219         assert_string_equal(
1220                 "00000000-0000-0000-0000-000000000000",
1221                 json_string_value(v));
1222
1223         v = json_object_get(audit, "objectCount");
1224         assert_non_null(v);
1225         assert_true(json_is_integer(v));
1226         assert_int_equal(0, json_integer_value(v));
1227
1228         v = json_object_get(audit, "linkCount");
1229         assert_non_null(v);
1230         assert_true(json_is_integer(v));
1231         assert_int_equal(0, json_integer_value(v));
1232
1233         v = json_object_get(audit, "partitionDN");
1234         assert_non_null(v);
1235         assert_true(json_is_null(v));
1236
1237         v = json_object_get(audit, "error");
1238         assert_non_null(v);
1239         assert_true(json_is_string(v));
1240         assert_string_equal(
1241                 "The operation completed successfully.",
1242                 json_string_value(v));
1243
1244         v = json_object_get(audit, "errorCode");
1245         assert_non_null(v);
1246         assert_true(json_is_integer(v));
1247         assert_int_equal(0, json_integer_value(v));
1248
1249         v = json_object_get(audit, "sourceDsa");
1250         assert_non_null(v);
1251         assert_true(json_is_string(v));
1252         assert_string_equal(
1253                 "00000000-0000-0000-0000-000000000000",
1254                 json_string_value(v));
1255
1256         v = json_object_get(audit, "invocationId");
1257         assert_non_null(v);
1258         assert_true(json_is_string(v));
1259         assert_string_equal(
1260                 "00000000-0000-0000-0000-000000000000",
1261                 json_string_value(v));
1262
1263         json_free(&json);
1264         TALLOC_FREE(ctx);
1265
1266 }
1267
1268 /*
1269  * unit test of replicated_update_json, that ensures that all the expected
1270  * attributes and objects are in the json object.
1271  */
1272 static void test_replicated_update_json(void **state)
1273 {
1274         struct ldb_context *ldb = NULL;
1275         struct ldb_module  *module = NULL;
1276         struct ldb_request *req = NULL;
1277         struct ldb_reply *reply = NULL;
1278         struct audit_private *audit_private = NULL;
1279         struct dsdb_extended_replicated_objects *ro = NULL;
1280         struct repsFromTo1 *source_dsa = NULL;
1281
1282         struct GUID transaction_id;
1283         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
1284
1285         struct ldb_dn *dn = NULL;
1286         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
1287
1288         struct GUID source_dsa_obj_guid;
1289         const char *const SOURCE_DSA = "7130cb06-2062-6a1b-409e-3514c26b1793";
1290
1291         struct GUID invocation_id;
1292         const char *const INVOCATION_ID =
1293                 "7130cb06-2062-6a1b-409e-3514c26b1893";
1294         struct json_object json;
1295         json_t *audit = NULL;
1296         json_t *v = NULL;
1297         json_t *o = NULL;
1298         time_t before;
1299
1300
1301         TALLOC_CTX *ctx = talloc_new(NULL);
1302
1303         ldb = ldb_init(ctx, NULL);
1304
1305         audit_private = talloc_zero(ctx, struct audit_private);
1306         GUID_from_string(TRANSACTION, &transaction_id);
1307         audit_private->transaction_guid = transaction_id;
1308
1309         module = talloc_zero(ctx, struct ldb_module);
1310         module->ldb = ldb;
1311         ldb_module_set_private(module, audit_private);
1312
1313         dn = ldb_dn_new(ctx, ldb, DN);
1314         GUID_from_string(SOURCE_DSA, &source_dsa_obj_guid);
1315         GUID_from_string(INVOCATION_ID, &invocation_id);
1316         source_dsa = talloc_zero(ctx, struct repsFromTo1);
1317         source_dsa->source_dsa_obj_guid = source_dsa_obj_guid;
1318         source_dsa->source_dsa_invocation_id = invocation_id;
1319
1320         ro = talloc_zero(ctx, struct dsdb_extended_replicated_objects);
1321         ro->source_dsa = source_dsa;
1322         ro->num_objects = 808;
1323         ro->linked_attributes_count = 2910;
1324         ro->partition_dn = dn;
1325         ro->error = WERR_NOT_SUPPORTED;
1326
1327
1328         req = talloc_zero(ctx, struct ldb_request);
1329         req->op.extended.data = ro;
1330         req->operation = LDB_EXTENDED;
1331
1332         reply = talloc_zero(ctx, struct ldb_reply);
1333         reply->error = LDB_ERR_NO_SUCH_OBJECT;
1334
1335         before = time(NULL);
1336         json = replicated_update_json(module, req, reply);
1337         assert_int_equal(3, json_object_size(json.root));
1338
1339
1340         v = json_object_get(json.root, "type");
1341         assert_non_null(v);
1342         assert_string_equal("replicatedUpdate", json_string_value(v));
1343
1344         v = json_object_get(json.root, "timestamp");
1345         assert_non_null(v);
1346         assert_true(json_is_string(v));
1347         check_timestamp(before, json_string_value(v));
1348
1349         audit = json_object_get(json.root, "replicatedUpdate");
1350         assert_non_null(audit);
1351         assert_true(json_is_object(audit));
1352         assert_int_equal(11, json_object_size(audit));
1353
1354         o = json_object_get(audit, "version");
1355         assert_non_null(o);
1356         check_version(o, REPLICATION_MAJOR, REPLICATION_MINOR);
1357
1358         v = json_object_get(audit, "statusCode");
1359         assert_non_null(v);
1360         assert_true(json_is_integer(v));
1361         assert_int_equal(LDB_ERR_NO_SUCH_OBJECT, json_integer_value(v));
1362
1363         v = json_object_get(audit, "status");
1364         assert_non_null(v);
1365         assert_true(json_is_string(v));
1366         assert_string_equal("No such object", json_string_value(v));
1367
1368         v = json_object_get(audit, "transactionId");
1369         assert_non_null(v);
1370         assert_true(json_is_string(v));
1371         assert_string_equal(TRANSACTION, json_string_value(v));
1372
1373         v = json_object_get(audit, "objectCount");
1374         assert_non_null(v);
1375         assert_true(json_is_integer(v));
1376         assert_int_equal(808, json_integer_value(v));
1377
1378         v = json_object_get(audit, "linkCount");
1379         assert_non_null(v);
1380         assert_true(json_is_integer(v));
1381         assert_int_equal(2910, json_integer_value(v));
1382
1383         v = json_object_get(audit, "partitionDN");
1384         assert_non_null(v);
1385         assert_true(json_is_string(v));
1386         assert_string_equal(DN, json_string_value(v));
1387
1388         v = json_object_get(audit, "error");
1389         assert_non_null(v);
1390         assert_true(json_is_string(v));
1391         assert_string_equal(
1392                 "The request is not supported.",
1393                 json_string_value(v));
1394
1395         v = json_object_get(audit, "errorCode");
1396         assert_non_null(v);
1397         assert_true(json_is_integer(v));
1398         assert_int_equal(W_ERROR_V(WERR_NOT_SUPPORTED), json_integer_value(v));
1399
1400         v = json_object_get(audit, "sourceDsa");
1401         assert_non_null(v);
1402         assert_true(json_is_string(v));
1403         assert_string_equal(SOURCE_DSA, json_string_value(v));
1404
1405         v = json_object_get(audit, "invocationId");
1406         assert_non_null(v);
1407         assert_true(json_is_string(v));
1408         assert_string_equal(INVOCATION_ID, json_string_value(v));
1409
1410         json_free(&json);
1411         TALLOC_FREE(ctx);
1412
1413 }
1414
1415 /*
1416  * minimal unit test of operation_human_readable, that ensures that all the
1417  * expected attributes and objects are in the json object.
1418  */
1419 static void test_operation_hr_empty(void **state)
1420 {
1421         struct ldb_context *ldb = NULL;
1422         struct ldb_module  *module = NULL;
1423         struct ldb_request *req = NULL;
1424         struct ldb_reply *reply = NULL;
1425         struct audit_private *audit_private = NULL;
1426
1427         char *line = NULL;
1428         const char *rs = NULL;
1429         regex_t regex;
1430
1431         int ret;
1432
1433         TALLOC_CTX *ctx = talloc_new(NULL);
1434
1435         ldb = ldb_init(ctx, NULL);
1436         audit_private = talloc_zero(ctx, struct audit_private);
1437
1438         module = talloc_zero(ctx, struct ldb_module);
1439         module->ldb = ldb;
1440         ldb_module_set_private(module, audit_private);
1441
1442         req = talloc_zero(ctx, struct ldb_request);
1443         reply = talloc_zero(ctx, struct ldb_reply);
1444         reply->error = LDB_SUCCESS;
1445
1446         line = operation_human_readable(ctx, module, req, reply);
1447         assert_non_null(line);
1448
1449         /*
1450          * We ignore the timestamp to make this test a little easier
1451          * to write.
1452          */
1453         rs =    "\\[Search] at \\["
1454                 "[^[]*"
1455                 "\\] status \\[Success\\] remote host \\[Unknown\\]"
1456                 " SID \\[(NULL SID)\\] DN \\[(null)\\]";
1457
1458         ret = regcomp(&regex, rs, 0);
1459         assert_int_equal(0, ret);
1460
1461         ret = regexec(&regex, line, 0, NULL, 0);
1462         assert_int_equal(0, ret);
1463
1464         regfree(&regex);
1465         TALLOC_FREE(ctx);
1466
1467 }
1468
1469 /*
1470  * unit test of operation_json, that ensures that all the expected
1471  * attributes and objects are in the json object.
1472  */
1473 static void test_operation_hr(void **state)
1474 {
1475         struct ldb_context *ldb = NULL;
1476         struct ldb_module  *module = NULL;
1477         struct ldb_request *req = NULL;
1478         struct ldb_reply *reply = NULL;
1479         struct audit_private *audit_private = NULL;
1480
1481         struct tsocket_address *ts = NULL;
1482
1483         struct auth_session_info *sess = NULL;
1484         struct security_token *token = NULL;
1485         struct dom_sid sid;
1486         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
1487         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
1488         struct GUID session_id;
1489
1490         struct GUID transaction_id;
1491         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
1492
1493         struct ldb_dn *dn = NULL;
1494         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
1495
1496         struct ldb_message *msg = NULL;
1497
1498         char *line = NULL;
1499         const char *rs = NULL;
1500         regex_t regex;
1501
1502         int ret;
1503
1504
1505         TALLOC_CTX *ctx = talloc_new(NULL);
1506
1507         ldb = ldb_init(ctx, NULL);
1508
1509         audit_private = talloc_zero(ctx, struct audit_private);
1510         GUID_from_string(TRANSACTION, &transaction_id);
1511         audit_private->transaction_guid = transaction_id;
1512
1513         module = talloc_zero(ctx, struct ldb_module);
1514         module->ldb = ldb;
1515         ldb_module_set_private(module, audit_private);
1516
1517         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
1518         ldb_set_opaque(ldb, "remoteAddress", ts);
1519
1520         sess = talloc_zero(ctx, struct auth_session_info);
1521         token = talloc_zero(ctx, struct security_token);
1522         string_to_sid(&sid, SID);
1523         token->num_sids = 1;
1524         token->sids = &sid;
1525         sess->security_token = token;
1526         GUID_from_string(SESSION, &session_id);
1527         sess->unique_session_token = session_id;
1528         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
1529
1530         msg = talloc_zero(ctx, struct ldb_message);
1531         dn = ldb_dn_new(ctx, ldb, DN);
1532         msg->dn = dn;
1533         ldb_msg_add_string(msg, "attribute", "the-value");
1534
1535         req = talloc_zero(ctx, struct ldb_request);
1536         req->operation =  LDB_ADD;
1537         req->op.add.message = msg;
1538         reply = talloc_zero(ctx, struct ldb_reply);
1539         reply->error = LDB_SUCCESS;
1540
1541         line = operation_human_readable(ctx, module, req, reply);
1542         assert_non_null(line);
1543
1544         /*
1545          * We ignore the timestamp to make this test a little easier
1546          * to write.
1547          */
1548         rs =    "\\[Add\\] at \\["
1549                 "[^]]*"
1550                 "\\] status \\[Success\\] "
1551                 "remote host \\[ipv4:127.0.0.1:0\\] "
1552                 "SID \\[S-1-5-21-2470180966-3899876309-2637894779\\] "
1553                 "DN \\[dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG\\] "
1554                 "attributes \\[attribute \\[the-value\\]\\]";
1555
1556         ret = regcomp(&regex, rs, 0);
1557         assert_int_equal(0, ret);
1558
1559         ret = regexec(&regex, line, 0, NULL, 0);
1560         assert_int_equal(0, ret);
1561
1562         regfree(&regex);
1563         TALLOC_FREE(ctx);
1564 }
1565
1566 /*
1567  * unit test of operation_json, that ensures that all the expected
1568  * attributes and objects are in the json object.
1569  * In this case the operation is being performed in a system session.
1570  */
1571 static void test_as_system_operation_hr(void **state)
1572 {
1573         struct ldb_context *ldb = NULL;
1574         struct ldb_module  *module = NULL;
1575         struct ldb_request *req = NULL;
1576         struct ldb_reply *reply = NULL;
1577         struct audit_private *audit_private = NULL;
1578
1579         struct tsocket_address *ts = NULL;
1580
1581         struct auth_session_info *sess = NULL;
1582         struct auth_session_info *sys_sess = NULL;
1583         struct security_token *token = NULL;
1584         struct security_token *sys_token = NULL;
1585         struct dom_sid sid;
1586         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
1587         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
1588         const char * const SYS_SESSION = "7130cb06-2062-6a1b-409e-3514c26b1999";
1589         struct GUID session_id;
1590         struct GUID sys_session_id;
1591
1592         struct GUID transaction_id;
1593         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
1594
1595         struct ldb_dn *dn = NULL;
1596         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
1597
1598         struct ldb_message *msg = NULL;
1599
1600         char *line = NULL;
1601         const char *rs = NULL;
1602         regex_t regex;
1603
1604         int ret;
1605
1606
1607         TALLOC_CTX *ctx = talloc_new(NULL);
1608
1609         ldb = ldb_init(ctx, NULL);
1610
1611         audit_private = talloc_zero(ctx, struct audit_private);
1612         GUID_from_string(TRANSACTION, &transaction_id);
1613         audit_private->transaction_guid = transaction_id;
1614
1615         module = talloc_zero(ctx, struct ldb_module);
1616         module->ldb = ldb;
1617         ldb_module_set_private(module, audit_private);
1618
1619         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
1620         ldb_set_opaque(ldb, "remoteAddress", ts);
1621
1622         sess = talloc_zero(ctx, struct auth_session_info);
1623         token = talloc_zero(ctx, struct security_token);
1624         string_to_sid(&sid, SID);
1625         token->num_sids = 1;
1626         token->sids = &sid;
1627         sess->security_token = token;
1628         GUID_from_string(SESSION, &session_id);
1629         sess->unique_session_token = session_id;
1630         ldb_set_opaque(ldb, DSDB_NETWORK_SESSION_INFO, sess);
1631
1632         sys_sess = talloc_zero(ctx, struct auth_session_info);
1633         sys_token = talloc_zero(ctx, struct security_token);
1634         sys_token->num_sids = 1;
1635         sys_token->sids = discard_const(&global_sid_System);
1636         sys_sess->security_token = sys_token;
1637         GUID_from_string(SYS_SESSION, &sys_session_id);
1638         sess->unique_session_token = sys_session_id;
1639         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sys_sess);
1640
1641         msg = talloc_zero(ctx, struct ldb_message);
1642         dn = ldb_dn_new(ctx, ldb, DN);
1643         msg->dn = dn;
1644         ldb_msg_add_string(msg, "attribute", "the-value");
1645
1646         req = talloc_zero(ctx, struct ldb_request);
1647         req->operation =  LDB_ADD;
1648         req->op.add.message = msg;
1649         reply = talloc_zero(ctx, struct ldb_reply);
1650         reply->error = LDB_SUCCESS;
1651
1652         line = operation_human_readable(ctx, module, req, reply);
1653         assert_non_null(line);
1654
1655         /*
1656          * We ignore the timestamp to make this test a little easier
1657          * to write.
1658          */
1659         rs =    "\\[Add\\] at \\["
1660                 "[^]]*"
1661                 "\\] status \\[Success\\] "
1662                 "remote host \\[ipv4:127.0.0.1:0\\] "
1663                 "SID \\[S-1-5-21-2470180966-3899876309-2637894779\\] "
1664                 "DN \\[dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG\\] "
1665                 "attributes \\[attribute \\[the-value\\]\\]";
1666
1667         ret = regcomp(&regex, rs, 0);
1668         assert_int_equal(0, ret);
1669
1670         ret = regexec(&regex, line, 0, NULL, 0);
1671         assert_int_equal(0, ret);
1672
1673         regfree(&regex);
1674         TALLOC_FREE(ctx);
1675 }
1676
1677 /*
1678  * minimal unit test of password_change_json, that ensures that all the expected
1679  * attributes and objects are in the json object.
1680  */
1681 static void test_password_change_hr_empty(void **state)
1682 {
1683         struct ldb_context *ldb = NULL;
1684         struct ldb_module  *module = NULL;
1685         struct ldb_request *req = NULL;
1686         struct ldb_reply *reply = NULL;
1687         struct audit_private *audit_private = NULL;
1688
1689         char *line = NULL;
1690         const char *rs = NULL;
1691         regex_t regex;
1692         int ret;
1693
1694         TALLOC_CTX *ctx = talloc_new(NULL);
1695
1696         ldb = ldb_init(ctx, NULL);
1697         audit_private = talloc_zero(ctx, struct audit_private);
1698
1699         module = talloc_zero(ctx, struct ldb_module);
1700         module->ldb = ldb;
1701         ldb_module_set_private(module, audit_private);
1702
1703         req = talloc_zero(ctx, struct ldb_request);
1704         reply = talloc_zero(ctx, struct ldb_reply);
1705         reply->error = LDB_SUCCESS;
1706
1707         line = password_change_human_readable(ctx, module, req, reply);
1708         assert_non_null(line);
1709
1710         /*
1711          * We ignore the timestamp to make this test a little easier
1712          * to write.
1713          */
1714         rs =    "\\[Reset] at \\["
1715                 "[^[]*"
1716                 "\\] status \\[Success\\] remote host \\[Unknown\\]"
1717                 " SID \\[(NULL SID)\\] DN \\[(null)\\]";
1718
1719         ret = regcomp(&regex, rs, 0);
1720         assert_int_equal(0, ret);
1721
1722         ret = regexec(&regex, line, 0, NULL, 0);
1723         assert_int_equal(0, ret);
1724
1725         regfree(&regex);
1726         TALLOC_FREE(ctx);
1727 }
1728
1729 /*
1730  * minimal unit test of password_change_json, that ensures that all the expected
1731  * attributes and objects are in the json object.
1732  */
1733 static void test_password_change_hr(void **state)
1734 {
1735         struct ldb_context *ldb = NULL;
1736         struct ldb_module  *module = NULL;
1737         struct ldb_request *req = NULL;
1738         struct ldb_reply *reply = NULL;
1739         struct audit_private *audit_private = NULL;
1740
1741         struct tsocket_address *ts = NULL;
1742
1743         struct auth_session_info *sess = NULL;
1744         struct security_token *token = NULL;
1745         struct dom_sid sid;
1746         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
1747         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
1748         struct GUID session_id;
1749
1750         struct GUID transaction_id;
1751         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
1752
1753         struct ldb_dn *dn = NULL;
1754         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
1755
1756         struct ldb_message *msg = NULL;
1757
1758         char *line = NULL;
1759         const char *rs = NULL;
1760         regex_t regex;
1761         int ret;
1762
1763         TALLOC_CTX *ctx = talloc_new(NULL);
1764
1765         ldb = ldb_init(ctx, NULL);
1766
1767         audit_private = talloc_zero(ctx, struct audit_private);
1768         GUID_from_string(TRANSACTION, &transaction_id);
1769         audit_private->transaction_guid = transaction_id;
1770
1771         module = talloc_zero(ctx, struct ldb_module);
1772         module->ldb = ldb;
1773         ldb_module_set_private(module, audit_private);
1774
1775         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
1776         ldb_set_opaque(ldb, "remoteAddress", ts);
1777
1778         sess = talloc_zero(ctx, struct auth_session_info);
1779         token = talloc_zero(ctx, struct security_token);
1780         string_to_sid(&sid, SID);
1781         token->num_sids = 1;
1782         token->sids = &sid;
1783         sess->security_token = token;
1784         GUID_from_string(SESSION, &session_id);
1785         sess->unique_session_token = session_id;
1786         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
1787
1788         msg = talloc_zero(ctx, struct ldb_message);
1789         dn = ldb_dn_new(ctx, ldb, DN);
1790         msg->dn = dn;
1791         ldb_msg_add_string(msg, "planTextPassword", "super-secret");
1792
1793         req = talloc_zero(ctx, struct ldb_request);
1794         req->operation =  LDB_ADD;
1795         req->op.add.message = msg;
1796         reply = talloc_zero(ctx, struct ldb_reply);
1797         reply->error = LDB_SUCCESS;
1798
1799         line = password_change_human_readable(ctx, module, req, reply);
1800         assert_non_null(line);
1801
1802         /*
1803          * We ignore the timestamp to make this test a little easier
1804          * to write.
1805          */
1806         rs =    "\\[Reset\\] at \\["
1807                 "[^[]*"
1808                 "\\] status \\[Success\\] "
1809                 "remote host \\[ipv4:127.0.0.1:0\\] "
1810                 "SID \\[S-1-5-21-2470180966-3899876309-2637894779\\] "
1811                 "DN \\[dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG\\]";
1812
1813         ret = regcomp(&regex, rs, 0);
1814         assert_int_equal(0, ret);
1815
1816         ret = regexec(&regex, line, 0, NULL, 0);
1817         assert_int_equal(0, ret);
1818
1819         regfree(&regex);
1820         TALLOC_FREE(ctx);
1821
1822 }
1823
1824 /*
1825  * minimal unit test of transaction_json, that ensures that all the expected
1826  * attributes and objects are in the json object.
1827  */
1828 static void test_transaction_hr(void **state)
1829 {
1830
1831         struct GUID guid;
1832         const char * const GUID = "7130cb06-2062-6a1b-409e-3514c26b1773";
1833
1834         char *line = NULL;
1835         const char *rs = NULL;
1836         regex_t regex;
1837         int ret;
1838
1839         TALLOC_CTX *ctx = talloc_new(NULL);
1840
1841         GUID_from_string(GUID, &guid);
1842
1843         line = transaction_human_readable(ctx, "delete", 23);
1844         assert_non_null(line);
1845
1846         /*
1847          * We ignore the timestamp to make this test a little easier
1848          * to write.
1849          */
1850         rs = "\\[delete] at \\[[^[]*\\] duration \\[23\\]";
1851
1852         ret = regcomp(&regex, rs, 0);
1853         assert_int_equal(0, ret);
1854
1855         ret = regexec(&regex, line, 0, NULL, 0);
1856         assert_int_equal(0, ret);
1857
1858         regfree(&regex);
1859         TALLOC_FREE(ctx);
1860
1861 }
1862
1863 /*
1864  * minimal unit test of commit_failure_hr, that ensures
1865  * that all the expected conten is in the log entry.
1866  */
1867 static void test_commit_failure_hr(void **state)
1868 {
1869
1870         struct GUID guid;
1871         const char * const GUID = "7130cb06-2062-6a1b-409e-3514c26b1773";
1872
1873         char *line = NULL;
1874         const char *rs = NULL;
1875         regex_t regex;
1876         int ret;
1877
1878         TALLOC_CTX *ctx = talloc_new(NULL);
1879
1880         GUID_from_string(GUID, &guid);
1881
1882         line = commit_failure_human_readable(
1883                 ctx,
1884                 "commit",
1885                 789345,
1886                 LDB_ERR_OPERATIONS_ERROR,
1887                 "because");
1888
1889         assert_non_null(line);
1890
1891         /*
1892          * We ignore the timestamp to make this test a little easier
1893          * to write.
1894          */
1895         rs = "\\[commit\\] at \\[[^[]*\\] duration \\[789345\\] "
1896              "status \\[1\\] reason \\[because\\]";
1897
1898         ret = regcomp(&regex, rs, 0);
1899         assert_int_equal(0, ret);
1900
1901         ret = regexec(&regex, line, 0, NULL, 0);
1902         assert_int_equal(0, ret);
1903
1904         regfree(&regex);
1905         TALLOC_FREE(ctx);
1906 }
1907
1908 static void test_add_transaction_id(void **state)
1909 {
1910         struct ldb_module  *module = NULL;
1911         struct ldb_request *req = NULL;
1912         struct audit_private *audit_private = NULL;
1913         struct GUID guid;
1914         const char * const GUID = "7130cb06-2062-6a1b-409e-3514c26b1773";
1915         struct ldb_control * control = NULL;
1916         int status;
1917
1918         TALLOC_CTX *ctx = talloc_new(NULL);
1919
1920         audit_private = talloc_zero(ctx, struct audit_private);
1921         GUID_from_string(GUID, &guid);
1922         audit_private->transaction_guid = guid;
1923
1924         module = talloc_zero(ctx, struct ldb_module);
1925         ldb_module_set_private(module, audit_private);
1926
1927         req = talloc_zero(ctx, struct ldb_request);
1928
1929         status = add_transaction_id(module, req);
1930         assert_int_equal(LDB_SUCCESS, status);
1931
1932         control = ldb_request_get_control(
1933                 req,
1934                 DSDB_CONTROL_TRANSACTION_IDENTIFIER_OID);
1935         assert_non_null(control);
1936         assert_memory_equal(
1937                 &audit_private->transaction_guid,
1938                 control->data,
1939                 sizeof(struct GUID));
1940
1941         TALLOC_FREE(ctx);
1942 }
1943
1944 static void test_log_attributes(void **state)
1945 {
1946         struct ldb_message *msg = NULL;
1947
1948         char *buf = NULL;
1949         char *str = NULL;
1950         char lv[MAX_LENGTH+2];
1951         char ex[MAX_LENGTH+80];
1952
1953         TALLOC_CTX *ctx = talloc_new(NULL);
1954
1955
1956         /*
1957          * Test an empty message
1958          * Should get empty attributes representation.
1959          */
1960         buf = talloc_zero(ctx, char);
1961         msg = talloc_zero(ctx, struct ldb_message);
1962
1963         str = log_attributes(ctx, buf, LDB_ADD, msg);
1964         assert_string_equal("", str);
1965
1966         TALLOC_FREE(str);
1967         TALLOC_FREE(msg);
1968
1969         /*
1970          * Test a message with a single secret attribute
1971          */
1972         buf = talloc_zero(ctx, char);
1973         msg = talloc_zero(ctx, struct ldb_message);
1974         ldb_msg_add_string(msg, "clearTextPassword", "secret");
1975
1976         str = log_attributes(ctx, buf, LDB_ADD, msg);
1977         assert_string_equal(
1978                 "clearTextPassword [REDACTED SECRET ATTRIBUTE]",
1979                 str);
1980         TALLOC_FREE(str);
1981         /*
1982          * Test as a modify message, should add an action
1983          * action will be unknown as there are no ACL's set
1984          */
1985         buf = talloc_zero(ctx, char);
1986         str = log_attributes(ctx, buf, LDB_MODIFY, msg);
1987         assert_string_equal(
1988                 "unknown: clearTextPassword [REDACTED SECRET ATTRIBUTE]",
1989                 str);
1990
1991         TALLOC_FREE(str);
1992         TALLOC_FREE(msg);
1993
1994         /*
1995          * Test a message with a single attribute, single valued attribute
1996          */
1997         buf = talloc_zero(ctx, char);
1998         msg = talloc_zero(ctx, struct ldb_message);
1999         ldb_msg_add_string(msg, "attribute", "value");
2000
2001         str = log_attributes(ctx, buf, LDB_ADD, msg);
2002         assert_string_equal(
2003                 "attribute [value]",
2004                 str);
2005
2006         TALLOC_FREE(str);
2007         TALLOC_FREE(msg);
2008
2009         /*
2010          * Test a message with a single attribute, single valued attribute
2011          * And as a modify
2012          */
2013         buf = talloc_zero(ctx, char);
2014         msg = talloc_zero(ctx, struct ldb_message);
2015         ldb_msg_add_string(msg, "attribute", "value");
2016
2017         str = log_attributes(ctx, buf, LDB_MODIFY, msg);
2018         assert_string_equal(
2019                 "unknown: attribute [value]",
2020                 str);
2021
2022         TALLOC_FREE(str);
2023         TALLOC_FREE(msg);
2024
2025         /*
2026          * Test a message with multiple attributes and a multi-valued attribute
2027          *
2028          */
2029         buf = talloc_zero(ctx, char);
2030         msg = talloc_zero(ctx, struct ldb_message);
2031         ldb_msg_add_string(msg, "attribute01", "value01");
2032         ldb_msg_add_string(msg, "attribute02", "value02");
2033         ldb_msg_add_string(msg, "attribute02", "value03");
2034
2035         str = log_attributes(ctx, buf, LDB_MODIFY, msg);
2036         assert_string_equal(
2037                 "unknown: attribute01 [value01] "
2038                 "unknown: attribute02 [value02] [value03]",
2039                 str);
2040
2041         TALLOC_FREE(str);
2042         TALLOC_FREE(msg);
2043
2044         /*
2045          * Test a message with a single attribute, single valued attribute
2046          * with a non printable character. Should be base64 encoded
2047          */
2048         buf = talloc_zero(ctx, char);
2049         msg = talloc_zero(ctx, struct ldb_message);
2050         ldb_msg_add_string(msg, "attribute", "value\n");
2051
2052         str = log_attributes(ctx, buf, LDB_ADD, msg);
2053         assert_string_equal("attribute {dmFsdWUK}", str);
2054
2055         TALLOC_FREE(str);
2056         TALLOC_FREE(msg);
2057
2058         /*
2059          * Test a message with a single valued attribute
2060          * with more than MAX_LENGTH characters, should be truncated with
2061          * trailing ...
2062          */
2063         buf = talloc_zero(ctx, char);
2064         msg = talloc_zero(ctx, struct ldb_message);
2065         memset(lv, '\0', sizeof(lv));
2066         memset(lv, 'x', MAX_LENGTH+1);
2067         ldb_msg_add_string(msg, "attribute", lv);
2068
2069         str = log_attributes(ctx, buf, LDB_ADD, msg);
2070         snprintf(ex, sizeof(ex), "attribute [%.*s...]", MAX_LENGTH, lv);
2071         assert_string_equal(ex, str);
2072
2073         TALLOC_FREE(str);
2074         TALLOC_FREE(msg);
2075
2076         TALLOC_FREE(ctx);
2077 }
2078
2079 /*
2080  * minimal unit test of replicated_update_human_readable
2081  */
2082 static void test_replicated_update_hr_empty(void **state)
2083 {
2084         struct ldb_context *ldb = NULL;
2085         struct ldb_module  *module = NULL;
2086         struct ldb_request *req = NULL;
2087         struct ldb_reply *reply = NULL;
2088         struct audit_private *audit_private = NULL;
2089         struct dsdb_extended_replicated_objects *ro = NULL;
2090         struct repsFromTo1 *source_dsa = NULL;
2091
2092         const char* line = NULL;
2093         const char *rs = NULL;
2094         regex_t regex;
2095         int ret;
2096
2097         TALLOC_CTX *ctx = talloc_new(NULL);
2098
2099         ldb = ldb_init(ctx, NULL);
2100         audit_private = talloc_zero(ctx, struct audit_private);
2101
2102         module = talloc_zero(ctx, struct ldb_module);
2103         module->ldb = ldb;
2104         ldb_module_set_private(module, audit_private);
2105
2106         source_dsa = talloc_zero(ctx, struct repsFromTo1);
2107         ro = talloc_zero(ctx, struct dsdb_extended_replicated_objects);
2108         ro->source_dsa = source_dsa;
2109         req = talloc_zero(ctx, struct ldb_request);
2110         req->op.extended.data = ro;
2111         req->operation = LDB_EXTENDED;
2112         reply = talloc_zero(ctx, struct ldb_reply);
2113         reply->error = LDB_SUCCESS;
2114
2115         line = replicated_update_human_readable(ctx, module, req, reply);
2116         assert_non_null(line);
2117         /*
2118          * We ignore the timestamp to make this test a little easier
2119          * to write.
2120          */
2121         rs =    "at \\[[^[]*\\] "
2122                 "status \\[Success\\] "
2123                 "error \\[The operation completed successfully.\\] "
2124                 "partition \\[(null)\\] objects \\[0\\] links \\[0\\] "
2125                 "object \\[00000000-0000-0000-0000-000000000000\\] "
2126                 "invocation \\[00000000-0000-0000-0000-000000000000\\]";
2127
2128         ret = regcomp(&regex, rs, 0);
2129         assert_int_equal(0, ret);
2130
2131         ret = regexec(&regex, line, 0, NULL, 0);
2132         assert_int_equal(0, ret);
2133
2134         regfree(&regex);
2135         TALLOC_FREE(ctx);
2136
2137 }
2138
2139 /*
2140  * unit test of replicated_update_human_readable
2141  */
2142 static void test_replicated_update_hr(void **state)
2143 {
2144         struct ldb_context *ldb = NULL;
2145         struct ldb_module  *module = NULL;
2146         struct ldb_request *req = NULL;
2147         struct ldb_reply *reply = NULL;
2148         struct audit_private *audit_private = NULL;
2149         struct dsdb_extended_replicated_objects *ro = NULL;
2150         struct repsFromTo1 *source_dsa = NULL;
2151
2152         struct GUID transaction_id;
2153         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
2154
2155         struct ldb_dn *dn = NULL;
2156         const char *const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
2157
2158         struct GUID source_dsa_obj_guid;
2159         const char *const SOURCE_DSA = "7130cb06-2062-6a1b-409e-3514c26b1793";
2160
2161         struct GUID invocation_id;
2162         const char *const INVOCATION_ID =
2163                 "7130cb06-2062-6a1b-409e-3514c26b1893";
2164
2165         const char* line = NULL;
2166         const char *rs = NULL;
2167         regex_t regex;
2168         int ret;
2169
2170
2171         TALLOC_CTX *ctx = talloc_new(NULL);
2172
2173         ldb = ldb_init(ctx, NULL);
2174
2175         audit_private = talloc_zero(ctx, struct audit_private);
2176         GUID_from_string(TRANSACTION, &transaction_id);
2177         audit_private->transaction_guid = transaction_id;
2178
2179         module = talloc_zero(ctx, struct ldb_module);
2180         module->ldb = ldb;
2181         ldb_module_set_private(module, audit_private);
2182
2183         dn = ldb_dn_new(ctx, ldb, DN);
2184         GUID_from_string(SOURCE_DSA, &source_dsa_obj_guid);
2185         GUID_from_string(INVOCATION_ID, &invocation_id);
2186         source_dsa = talloc_zero(ctx, struct repsFromTo1);
2187         source_dsa->source_dsa_obj_guid = source_dsa_obj_guid;
2188         source_dsa->source_dsa_invocation_id = invocation_id;
2189
2190         ro = talloc_zero(ctx, struct dsdb_extended_replicated_objects);
2191         ro->source_dsa = source_dsa;
2192         ro->num_objects = 808;
2193         ro->linked_attributes_count = 2910;
2194         ro->partition_dn = dn;
2195         ro->error = WERR_NOT_SUPPORTED;
2196
2197
2198         req = talloc_zero(ctx, struct ldb_request);
2199         req->op.extended.data = ro;
2200         req->operation = LDB_EXTENDED;
2201
2202         reply = talloc_zero(ctx, struct ldb_reply);
2203         reply->error = LDB_ERR_NO_SUCH_OBJECT;
2204
2205         line = replicated_update_human_readable(ctx, module, req, reply);
2206         assert_non_null(line);
2207
2208         /*
2209          * We ignore the timestamp to make this test a little easier
2210          * to write.
2211          */
2212         rs =    "at \\[[^[]*\\] "
2213                 "status \\[No such object\\] "
2214                 "error \\[The request is not supported.\\] "
2215                 "partition \\[dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG\\] "
2216                 "objects \\[808\\] links \\[2910\\] "
2217                 "object \\[7130cb06-2062-6a1b-409e-3514c26b1793\\] "
2218                 "invocation \\[7130cb06-2062-6a1b-409e-3514c26b1893\\]";
2219
2220         ret = regcomp(&regex, rs, 0);
2221         assert_int_equal(0, ret);
2222
2223         ret = regexec(&regex, line, 0, NULL, 0);
2224         assert_int_equal(0, ret);
2225
2226         regfree(&regex);
2227         TALLOC_FREE(ctx);
2228 }
2229
2230 int main(void) {
2231         const struct CMUnitTest tests[] = {
2232                 cmocka_unit_test(test_has_password_changed),
2233                 cmocka_unit_test(test_get_password_action),
2234                 cmocka_unit_test(test_operation_json_empty),
2235                 cmocka_unit_test(test_operation_json),
2236                 cmocka_unit_test(test_as_system_operation_json),
2237                 cmocka_unit_test(test_password_change_json_empty),
2238                 cmocka_unit_test(test_password_change_json),
2239                 cmocka_unit_test(test_transaction_json),
2240                 cmocka_unit_test(test_commit_failure_json),
2241                 cmocka_unit_test(test_replicated_update_json_empty),
2242                 cmocka_unit_test(test_replicated_update_json),
2243                 cmocka_unit_test(test_add_transaction_id),
2244                 cmocka_unit_test(test_operation_hr_empty),
2245                 cmocka_unit_test(test_operation_hr),
2246                 cmocka_unit_test(test_as_system_operation_hr),
2247                 cmocka_unit_test(test_password_change_hr_empty),
2248                 cmocka_unit_test(test_password_change_hr),
2249                 cmocka_unit_test(test_transaction_hr),
2250                 cmocka_unit_test(test_commit_failure_hr),
2251                 cmocka_unit_test(test_log_attributes),
2252                 cmocka_unit_test(test_replicated_update_hr_empty),
2253                 cmocka_unit_test(test_replicated_update_hr),
2254         };
2255
2256         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
2257         return cmocka_run_group_tests(tests, NULL, NULL);
2258 }