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