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(&regex, rs, 0);
1472 	assert_int_equal(0, ret);
1473 
1474 	ret = regexec(&regex, line, 0, NULL, 0);
1475 	assert_int_equal(0, ret);
1476 
1477 	regfree(&regex);
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(&regex, rs, 0);
1570 	assert_int_equal(0, ret);
1571 
1572 	ret = regexec(&regex, line, 0, NULL, 0);
1573 	assert_int_equal(0, ret);
1574 
1575 	regfree(&regex);
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(&regex, rs, 0);
1681 	assert_int_equal(0, ret);
1682 
1683 	ret = regexec(&regex, line, 0, NULL, 0);
1684 	assert_int_equal(0, ret);
1685 
1686 	regfree(&regex);
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(&regex, rs, 0);
1733 	assert_int_equal(0, ret);
1734 
1735 	ret = regexec(&regex, line, 0, NULL, 0);
1736 	assert_int_equal(0, ret);
1737 
1738 	regfree(&regex);
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(&regex, rs, 0);
1827 	assert_int_equal(0, ret);
1828 
1829 	ret = regexec(&regex, line, 0, NULL, 0);
1830 	assert_int_equal(0, ret);
1831 
1832 	regfree(&regex);
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(&regex, rs, 0);
1866 	assert_int_equal(0, ret);
1867 
1868 	ret = regexec(&regex, line, 0, NULL, 0);
1869 	assert_int_equal(0, ret);
1870 
1871 	regfree(&regex);
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(&regex, rs, 0);
1912 	assert_int_equal(0, ret);
1913 
1914 	ret = regexec(&regex, line, 0, NULL, 0);
1915 	assert_int_equal(0, ret);
1916 
1917 	regfree(&regex);
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(&regex, rs, 0);
2142 	assert_int_equal(0, ret);
2143 
2144 	ret = regexec(&regex, line, 0, NULL, 0);
2145 	assert_int_equal(0, ret);
2146 
2147 	regfree(&regex);
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(&regex, rs, 0);
2234 	assert_int_equal(0, ret);
2235 
2236 	ret = regexec(&regex, line, 0, NULL, 0);
2237 	assert_int_equal(0, ret);
2238 
2239 	regfree(&regex);
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