1 /*
2 Unit tests for the dsdb audit logging utility code code in audit_util.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 #include "../audit_util.c"
27
28 #include "lib/ldb/include/ldb_private.h"
29
test_dsdb_audit_add_ldb_value(void ** state)30 static void test_dsdb_audit_add_ldb_value(void **state)
31 {
32 struct json_object object;
33 struct json_object array;
34 struct ldb_val val = data_blob_null;
35 struct json_t *el = NULL;
36 struct json_t *atr = NULL;
37 char* base64 = NULL;
38
39 TALLOC_CTX *ctx = talloc_new(NULL);
40 /*
41 * Test a non array object
42 */
43 object = json_new_object();
44 assert_false(json_is_invalid(&object));
45 dsdb_audit_add_ldb_value(&object, val);
46 assert_true(json_is_invalid(&object));
47 json_free(&object);
48
49 array = json_new_array();
50 /*
51 * Test a data_blob_null, should encode as a JSON null value.
52 */
53 val = data_blob_null;
54 dsdb_audit_add_ldb_value(&array, val);
55 el = json_array_get(array.root, 0);
56 assert_true(json_is_null(el));
57
58 /*
59 * Test a +ve length but a null data ptr, should encode as a null.
60 */
61 val = data_blob_null;
62 val.length = 1;
63 dsdb_audit_add_ldb_value(&array, val);
64 el = json_array_get(array.root, 1);
65 assert_true(json_is_null(el));
66
67 /*
68 * Test a zero length but a non null data ptr, should encode as a null.
69 */
70 val = data_blob_null;
71 val.data = discard_const("Data on the stack");
72 dsdb_audit_add_ldb_value(&array, val);
73 el = json_array_get(array.root, 2);
74 assert_true(json_is_null(el));
75
76 /*
77 * Test a printable value.
78 * value should not be encoded
79 * truncated and base64 should be missing
80 */
81 val = data_blob_string_const("A value of interest");
82 dsdb_audit_add_ldb_value(&array, val);
83 el = json_array_get(array.root, 3);
84 assert_true(json_is_object(el));
85 atr = json_object_get(el, "value");
86 assert_true(json_is_string(atr));
87 assert_string_equal("A value of interest", json_string_value(atr));
88 assert_null(json_object_get(el, "truncated"));
89 assert_null(json_object_get(el, "base64"));
90
91 /*
92 * Test non printable value, should be base64 encoded.
93 * truncated should be missing and base64 should be set.
94 */
95 val = data_blob_string_const("A value of interest\n");
96 dsdb_audit_add_ldb_value(&array, val);
97 el = json_array_get(array.root, 4);
98 assert_true(json_is_object(el));
99 atr = json_object_get(el, "value");
100 assert_true(json_is_string(atr));
101 assert_string_equal(
102 "QSB2YWx1ZSBvZiBpbnRlcmVzdAo=",
103 json_string_value(atr));
104 atr = json_object_get(el, "base64");
105 assert_true(json_is_boolean(atr));
106 assert_true(json_boolean(atr));
107 assert_null(json_object_get(el, "truncated"));
108
109 /*
110 * test a printable value exactly max bytes long
111 * should not be truncated or encoded.
112 */
113 val = data_blob_null;
114 val.length = MAX_LENGTH;
115 val.data = (unsigned char *)generate_random_str_list(
116 ctx,
117 MAX_LENGTH,
118 "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
119 "1234567890!@#$%^&*()");
120
121 dsdb_audit_add_ldb_value(&array, val);
122
123 el = json_array_get(array.root, 5);
124 assert_true(json_is_object(el));
125 atr = json_object_get(el, "value");
126 assert_true(json_is_string(atr));
127 assert_int_equal(MAX_LENGTH, strlen(json_string_value(atr)));
128 assert_memory_equal(val.data, json_string_value(atr), MAX_LENGTH);
129
130 assert_null(json_object_get(el, "base64"));
131 assert_null(json_object_get(el, "truncated"));
132
133
134 /*
135 * test a printable value exactly max + 1 bytes long
136 * should be truncated and not encoded.
137 */
138 val = data_blob_null;
139 val.length = MAX_LENGTH + 1;
140 val.data = (unsigned char *)generate_random_str_list(
141 ctx,
142 MAX_LENGTH + 1,
143 "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
144 "1234567890!@#$%^&*()");
145
146 dsdb_audit_add_ldb_value(&array, val);
147
148 el = json_array_get(array.root, 6);
149 assert_true(json_is_object(el));
150 atr = json_object_get(el, "value");
151 assert_true(json_is_string(atr));
152 assert_int_equal(MAX_LENGTH, strlen(json_string_value(atr)));
153 assert_memory_equal(val.data, json_string_value(atr), MAX_LENGTH);
154
155 atr = json_object_get(el, "truncated");
156 assert_true(json_is_boolean(atr));
157 assert_true(json_boolean(atr));
158
159 assert_null(json_object_get(el, "base64"));
160
161 TALLOC_FREE(val.data);
162
163 /*
164 * test a non-printable value exactly max bytes long
165 * should not be truncated but should be encoded.
166 */
167 val = data_blob_null;
168 val.length = MAX_LENGTH;
169 val.data = (unsigned char *)generate_random_str_list(
170 ctx,
171 MAX_LENGTH,
172 "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
173 "1234567890!@#$%^&*()");
174
175 val.data[0] = 0x03;
176 dsdb_audit_add_ldb_value(&array, val);
177 base64 = ldb_base64_encode(ctx, (char*) val.data, MAX_LENGTH);
178
179 el = json_array_get(array.root, 7);
180 assert_true(json_is_object(el));
181 atr = json_object_get(el, "value");
182 assert_true(json_is_string(atr));
183 assert_int_equal(strlen(base64), strlen(json_string_value(atr)));
184 assert_string_equal(base64, json_string_value(atr));
185
186 atr = json_object_get(el, "base64");
187 assert_true(json_is_boolean(atr));
188 assert_true(json_boolean(atr));
189
190 assert_null(json_object_get(el, "truncated"));
191 TALLOC_FREE(base64);
192 TALLOC_FREE(val.data);
193
194 /*
195 * test a non-printable value exactly max + 1 bytes long
196 * should be truncated and encoded.
197 */
198 val = data_blob_null;
199 val.length = MAX_LENGTH + 1;
200 val.data = (unsigned char *)generate_random_str_list(
201 ctx,
202 MAX_LENGTH + 1,
203 "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
204 "1234567890!@#$%^&*()");
205
206 val.data[0] = 0x03;
207 dsdb_audit_add_ldb_value(&array, val);
208 /*
209 * The data is truncated before it is base 64 encoded
210 */
211 base64 = ldb_base64_encode(ctx, (char*) val.data, MAX_LENGTH);
212
213 el = json_array_get(array.root, 8);
214 assert_true(json_is_object(el));
215 atr = json_object_get(el, "value");
216 assert_true(json_is_string(atr));
217 assert_int_equal(strlen(base64), strlen(json_string_value(atr)));
218 assert_string_equal(base64, json_string_value(atr));
219
220 atr = json_object_get(el, "base64");
221 assert_true(json_is_boolean(atr));
222 assert_true(json_boolean(atr));
223
224 atr = json_object_get(el, "truncated");
225 assert_true(json_is_boolean(atr));
226 assert_true(json_boolean(atr));
227
228 TALLOC_FREE(base64);
229 TALLOC_FREE(val.data);
230
231 json_free(&array);
232 TALLOC_FREE(ctx);
233 }
234
test_dsdb_audit_attributes_json(void ** state)235 static void test_dsdb_audit_attributes_json(void **state)
236 {
237 struct ldb_message *msg = NULL;
238
239 struct json_object o;
240 json_t *a = NULL;
241 json_t *v = NULL;
242 json_t *x = NULL;
243 json_t *y = NULL;
244
245 TALLOC_CTX *ctx = talloc_new(NULL);
246
247
248 /*
249 * Test an empty message
250 * Should get an empty attributes object
251 */
252 msg = talloc_zero(ctx, struct ldb_message);
253
254 o = dsdb_audit_attributes_json(LDB_ADD, msg);
255 assert_true(json_is_object(o.root));
256 assert_int_equal(0, json_object_size(o.root));
257 json_free(&o);
258
259 o = dsdb_audit_attributes_json(LDB_MODIFY, msg);
260 assert_true(json_is_object(o.root));
261 assert_int_equal(0, json_object_size(o.root));
262 json_free(&o);
263
264 /*
265 * Test a message with a single secret attribute
266 * should only have that object and it should have no value
267 * attribute and redacted should be set.
268 */
269 msg = talloc_zero(ctx, struct ldb_message);
270 ldb_msg_add_string(msg, "clearTextPassword", "secret");
271
272 o = dsdb_audit_attributes_json(LDB_ADD, msg);
273 assert_true(json_is_object(o.root));
274 assert_int_equal(1, json_object_size(o.root));
275
276 a = json_object_get(o.root, "clearTextPassword");
277 assert_int_equal(1, json_object_size(a));
278
279 v = json_object_get(a, "actions");
280 assert_true(json_is_array(v));
281 assert_int_equal(1, json_array_size(v));
282
283 a = json_array_get(v, 0);
284 v = json_object_get(a, "redacted");
285 assert_true(json_is_boolean(v));
286 assert_true(json_boolean(v));
287
288 json_free(&o);
289
290 /*
291 * Test as a modify message, should add an action attribute
292 */
293 o = dsdb_audit_attributes_json(LDB_MODIFY, msg);
294 assert_true(json_is_object(o.root));
295 assert_int_equal(1, json_object_size(o.root));
296
297 a = json_object_get(o.root, "clearTextPassword");
298 assert_true(json_is_object(a));
299 assert_int_equal(1, json_object_size(a));
300
301 v = json_object_get(a, "actions");
302 assert_true(json_is_array(v));
303 assert_int_equal(1, json_array_size(v));
304
305 a = json_array_get(v, 0);
306 v = json_object_get(a, "redacted");
307 assert_true(json_is_boolean(v));
308 assert_true(json_boolean(v));
309
310 v = json_object_get(a, "action");
311 assert_true(json_is_string(v));
312 assert_string_equal("unknown", json_string_value(v));
313
314 json_free(&o);
315 TALLOC_FREE(msg);
316
317 /*
318 * Test a message with a single attribute, single valued attribute
319 */
320 msg = talloc_zero(ctx, struct ldb_message);
321 ldb_msg_add_string(msg, "attribute", "value");
322
323 o = dsdb_audit_attributes_json(LDB_ADD, msg);
324 assert_true(json_is_object(o.root));
325 assert_int_equal(1, json_object_size(o.root));
326
327 a = json_object_get(o.root, "attribute");
328 assert_true(json_is_object(a));
329 assert_int_equal(1, json_object_size(a));
330
331 v = json_object_get(a, "actions");
332 assert_true(json_is_array(v));
333 assert_int_equal(1, json_array_size(v));
334
335 x = json_array_get(v, 0);
336 assert_int_equal(2, json_object_size(x));
337 y = json_object_get(x, "action");
338 assert_string_equal("add", json_string_value(y));
339
340 y = json_object_get(x, "values");
341 assert_true(json_is_array(y));
342 assert_int_equal(1, json_array_size(y));
343
344 x = json_array_get(y, 0);
345 assert_true(json_is_object(x));
346 assert_int_equal(1, json_object_size(x));
347 y = json_object_get(x, "value");
348 assert_string_equal("value", json_string_value(y));
349
350 json_free(&o);
351 TALLOC_FREE(msg);
352
353 /*
354 * Test a message with a single attribute, single valued attribute
355 * And as a modify
356 */
357 msg = talloc_zero(ctx, struct ldb_message);
358 ldb_msg_add_string(msg, "attribute", "value");
359
360 o = dsdb_audit_attributes_json(LDB_MODIFY, msg);
361 assert_true(json_is_object(o.root));
362 assert_int_equal(1, json_object_size(o.root));
363
364 a = json_object_get(o.root, "attribute");
365 assert_true(json_is_object(a));
366 assert_int_equal(1, json_object_size(a));
367
368 v = json_object_get(a, "actions");
369 assert_true(json_is_array(v));
370 assert_int_equal(1, json_array_size(v));
371
372 x = json_array_get(v, 0);
373 assert_int_equal(2, json_object_size(x));
374 y = json_object_get(x, "action");
375 assert_string_equal("unknown", json_string_value(y));
376
377 y = json_object_get(x, "values");
378 assert_true(json_is_array(y));
379 assert_int_equal(1, json_array_size(y));
380
381 x = json_array_get(y, 0);
382 assert_true(json_is_object(x));
383 assert_int_equal(1, json_object_size(x));
384 y = json_object_get(x, "value");
385 assert_string_equal("value", json_string_value(y));
386
387 json_free(&o);
388 TALLOC_FREE(msg);
389
390 /*
391 * Test a message with a multivalues attributres
392 */
393 msg = talloc_zero(ctx, struct ldb_message);
394 ldb_msg_add_string(msg, "attribute01", "value01");
395 ldb_msg_add_string(msg, "attribute02", "value02");
396 ldb_msg_add_string(msg, "attribute02", "value03");
397
398 o = dsdb_audit_attributes_json(LDB_ADD, msg);
399 assert_true(json_is_object(o.root));
400 assert_int_equal(2, json_object_size(o.root));
401
402 a = json_object_get(o.root, "attribute01");
403 assert_true(json_is_object(a));
404 assert_int_equal(1, json_object_size(a));
405
406 v = json_object_get(a, "actions");
407 assert_true(json_is_array(v));
408 assert_int_equal(1, json_array_size(v));
409
410 x = json_array_get(v, 0);
411 assert_int_equal(2, json_object_size(x));
412 y = json_object_get(x, "action");
413 assert_string_equal("add", json_string_value(y));
414
415 y = json_object_get(x, "values");
416 assert_true(json_is_array(y));
417 assert_int_equal(1, json_array_size(y));
418
419 x = json_array_get(y, 0);
420 assert_true(json_is_object(x));
421 assert_int_equal(1, json_object_size(x));
422 y = json_object_get(x, "value");
423 assert_string_equal("value01", json_string_value(y));
424
425 a = json_object_get(o.root, "attribute02");
426 assert_true(json_is_object(a));
427 assert_int_equal(1, json_object_size(a));
428
429 v = json_object_get(a, "actions");
430 assert_true(json_is_array(v));
431 assert_int_equal(1, json_array_size(v));
432
433 x = json_array_get(v, 0);
434 assert_int_equal(2, json_object_size(x));
435 y = json_object_get(x, "action");
436 assert_string_equal("add", json_string_value(y));
437
438 y = json_object_get(x, "values");
439 assert_true(json_is_array(y));
440 assert_int_equal(2, json_array_size(y));
441
442 x = json_array_get(y, 0);
443 assert_true(json_is_object(x));
444 assert_int_equal(1, json_object_size(x));
445 v = json_object_get(x, "value");
446 assert_string_equal("value02", json_string_value(v));
447
448 x = json_array_get(y, 1);
449 assert_true(json_is_object(x));
450 assert_int_equal(1, json_object_size(x));
451 v = json_object_get(x, "value");
452 assert_string_equal("value03", json_string_value(v));
453
454 json_free(&o);
455 TALLOC_FREE(msg);
456
457 TALLOC_FREE(ctx);
458 }
459
test_dsdb_audit_get_remote_address(void ** state)460 static void test_dsdb_audit_get_remote_address(void **state)
461 {
462 struct ldb_context *ldb = NULL;
463 const struct tsocket_address *ts = NULL;
464 struct tsocket_address *in = NULL;
465
466 TALLOC_CTX *ctx = talloc_new(NULL);
467
468 /*
469 * Test a freshly initialized ldb
470 * should return NULL
471 */
472 ldb = ldb_init(ctx, NULL);
473 ts = dsdb_audit_get_remote_address(ldb);
474 assert_null(ts);
475
476 /*
477 * opaque set to null, should return NULL
478 */
479 ldb_set_opaque(ldb, "remoteAddress", NULL);
480 ts = dsdb_audit_get_remote_address(ldb);
481 assert_null(ts);
482
483 /*
484 * Ensure that the value set is returned
485 */
486 tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &in);
487 ldb_set_opaque(ldb, "remoteAddress", in);
488 ts = dsdb_audit_get_remote_address(ldb);
489 assert_non_null(ts);
490 assert_ptr_equal(in, ts);
491
492 TALLOC_FREE(ldb);
493 TALLOC_FREE(ctx);
494
495 }
496
test_dsdb_audit_get_ldb_error_string(void ** state)497 static void test_dsdb_audit_get_ldb_error_string(void **state)
498 {
499 struct ldb_context *ldb = NULL;
500 struct ldb_module *module = NULL;
501 const char *s = NULL;
502 const char * const text = "Custom reason";
503
504 TALLOC_CTX *ctx = talloc_new(NULL);
505
506 ldb = ldb_init(ctx, NULL);
507 module = talloc_zero(ctx, struct ldb_module);
508 module->ldb = ldb;
509
510 /*
511 * No ldb error string set should get the default error description for
512 * the status code
513 */
514 s = dsdb_audit_get_ldb_error_string(module, LDB_ERR_OPERATIONS_ERROR);
515 assert_string_equal("Operations error", s);
516
517 /*
518 * Set the error string that should now be returned instead of the
519 * default description.
520 */
521 ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, text);
522 s = dsdb_audit_get_ldb_error_string(module, LDB_ERR_OPERATIONS_ERROR);
523 /*
524 * Only test the start of the string as ldb_error adds location data.
525 */
526 assert_int_equal(0, strncmp(text, s, strlen(text)));
527
528 TALLOC_FREE(ctx);
529 }
530
test_dsdb_audit_get_user_sid(void ** state)531 static void test_dsdb_audit_get_user_sid(void **state)
532 {
533 struct ldb_context *ldb = NULL;
534 struct ldb_module *module = NULL;
535 const struct dom_sid *sid = NULL;
536 struct auth_session_info *sess = NULL;
537 struct security_token *token = NULL;
538 struct dom_sid sids[2];
539 const char * const SID0 = "S-1-5-21-2470180966-3899876309-2637894779";
540 const char * const SID1 = "S-1-5-21-4284042908-2889457889-3672286761";
541 struct dom_sid_buf sid_buf;
542
543
544 TALLOC_CTX *ctx = talloc_new(NULL);
545
546 ldb = ldb_init(ctx, NULL);
547 module = talloc_zero(ctx, struct ldb_module);
548 module->ldb = ldb;
549
550 /*
551 * Freshly initialised structures, will be no session data
552 * so expect NULL
553 */
554 sid = dsdb_audit_get_user_sid(module);
555 assert_null(sid);
556
557 /*
558 * Now add a NULL session info
559 */
560 ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
561 sid = dsdb_audit_get_user_sid(module);
562 assert_null(sid);
563
564 /*
565 * Now add a session info with no user sid
566 */
567 sess = talloc_zero(ctx, struct auth_session_info);
568 ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
569 sid = dsdb_audit_get_user_sid(module);
570 assert_null(sid);
571
572 /*
573 * Now add an empty security token.
574 */
575 token = talloc_zero(ctx, struct security_token);
576 sess->security_token = token;
577 sid = dsdb_audit_get_user_sid(module);
578 assert_null(sid);
579
580 /*
581 * Add a single SID
582 */
583 string_to_sid(&sids[0], SID0);
584 token->num_sids = 1;
585 token->sids = sids;
586 sid = dsdb_audit_get_user_sid(module);
587 assert_non_null(sid);
588 dom_sid_str_buf(sid, &sid_buf);
589 assert_string_equal(SID0, sid_buf.buf);
590
591 /*
592 * Add a second SID, should still use the first SID
593 */
594 string_to_sid(&sids[1], SID1);
595 token->num_sids = 2;
596 sid = dsdb_audit_get_user_sid(module);
597 assert_non_null(sid);
598 dom_sid_str_buf(sid, &sid_buf);
599 assert_string_equal(SID0, sid_buf.buf);
600
601
602 /*
603 * Now test a null sid in the first position
604 */
605 token->num_sids = 1;
606 token->sids = NULL;
607 sid = dsdb_audit_get_user_sid(module);
608 assert_null(sid);
609
610 TALLOC_FREE(ctx);
611 }
612
test_dsdb_audit_get_actual_sid(void ** state)613 static void test_dsdb_audit_get_actual_sid(void **state)
614 {
615 struct ldb_context *ldb = NULL;
616 const struct dom_sid *sid = NULL;
617 struct auth_session_info *sess = NULL;
618 struct security_token *token = NULL;
619 struct dom_sid sids[2];
620 const char * const SID0 = "S-1-5-21-2470180966-3899876309-2637894779";
621 const char * const SID1 = "S-1-5-21-4284042908-2889457889-3672286761";
622 struct dom_sid_buf sid_buf;
623
624
625 TALLOC_CTX *ctx = talloc_new(NULL);
626
627 ldb = ldb_init(ctx, NULL);
628
629 /*
630 * Freshly initialised structures, will be no session data
631 * so expect NULL
632 */
633 sid = dsdb_audit_get_actual_sid(ldb);
634 assert_null(sid);
635
636 /*
637 * Now add a NULL session info
638 */
639 ldb_set_opaque(ldb, DSDB_NETWORK_SESSION_INFO, NULL);
640 sid = dsdb_audit_get_actual_sid(ldb);
641 assert_null(sid);
642
643 /*
644 * Now add a session info with no user sid
645 */
646 sess = talloc_zero(ctx, struct auth_session_info);
647 ldb_set_opaque(ldb, DSDB_NETWORK_SESSION_INFO, sess);
648 sid = dsdb_audit_get_actual_sid(ldb);
649 assert_null(sid);
650
651 /*
652 * Now add an empty security token.
653 */
654 token = talloc_zero(ctx, struct security_token);
655 sess->security_token = token;
656 sid = dsdb_audit_get_actual_sid(ldb);
657 assert_null(sid);
658
659 /*
660 * Add a single SID
661 */
662 string_to_sid(&sids[0], SID0);
663 token->num_sids = 1;
664 token->sids = sids;
665 sid = dsdb_audit_get_actual_sid(ldb);
666 assert_non_null(sid);
667 dom_sid_str_buf(sid, &sid_buf);
668 assert_string_equal(SID0, sid_buf.buf);
669
670 /*
671 * Add a second SID, should still use the first SID
672 */
673 string_to_sid(&sids[1], SID1);
674 token->num_sids = 2;
675 sid = dsdb_audit_get_actual_sid(ldb);
676 assert_non_null(sid);
677 dom_sid_str_buf(sid, &sid_buf);
678 assert_string_equal(SID0, sid_buf.buf);
679
680
681 /*
682 * Now test a null sid in the first position
683 */
684 token->num_sids = 1;
685 token->sids = NULL;
686 sid = dsdb_audit_get_actual_sid(ldb);
687 assert_null(sid);
688
689 TALLOC_FREE(ctx);
690 }
691
test_dsdb_audit_is_system_session(void ** state)692 static void test_dsdb_audit_is_system_session(void **state)
693 {
694 struct ldb_context *ldb = NULL;
695 struct ldb_module *module = NULL;
696 const struct dom_sid *sid = NULL;
697 struct auth_session_info *sess = NULL;
698 struct security_token *token = NULL;
699 struct dom_sid sids[2];
700 const char * const SID0 = "S-1-5-21-2470180966-3899876309-2637894779";
701 const char * const SID1 = "S-1-5-21-4284042908-2889457889-3672286761";
702
703
704 TALLOC_CTX *ctx = talloc_new(NULL);
705
706 ldb = ldb_init(ctx, NULL);
707 module = talloc_zero(ctx, struct ldb_module);
708 module->ldb = ldb;
709
710 /*
711 * Freshly initialised structures, will be no session data
712 * so expect NULL
713 */
714 assert_false(dsdb_audit_is_system_session(module));
715
716 /*
717 * Now add a NULL session info
718 */
719 ldb_set_opaque(ldb, DSDB_SESSION_INFO, NULL);
720 assert_false(dsdb_audit_is_system_session(module));
721
722 /*
723 * Now add a session info with no user sid
724 */
725 sess = talloc_zero(ctx, struct auth_session_info);
726 ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
727 assert_false(dsdb_audit_is_system_session(module));
728
729 /*
730 * Now add an empty security token.
731 */
732 token = talloc_zero(ctx, struct security_token);
733 sess->security_token = token;
734 assert_false(dsdb_audit_is_system_session(module));
735
736 /*
737 * Add a single SID, non system sid
738 */
739 string_to_sid(&sids[0], SID0);
740 token->num_sids = 1;
741 token->sids = sids;
742 assert_false(dsdb_audit_is_system_session(module));
743
744 /*
745 * Add the system SID to the second position,
746 * this should be ignored.
747 */
748 token->num_sids = 2;
749 sids[1] = global_sid_System;
750 assert_false(dsdb_audit_is_system_session(module));
751
752 /*
753 * Add a single SID, system sid
754 */
755 token->num_sids = 1;
756 sids[0] = global_sid_System;
757 token->sids = sids;
758 assert_true(dsdb_audit_is_system_session(module));
759
760 /*
761 * Add a non system SID to position 2
762 */
763 sids[0] = global_sid_System;
764 string_to_sid(&sids[1], SID1);
765 token->num_sids = 2;
766 token->sids = sids;
767 assert_true(dsdb_audit_is_system_session(module));
768
769 /*
770 * Now test a null sid in the first position
771 */
772 token->num_sids = 1;
773 token->sids = NULL;
774 sid = dsdb_audit_get_user_sid(module);
775 assert_null(sid);
776
777 TALLOC_FREE(ctx);
778 }
779
test_dsdb_audit_get_unique_session_token(void ** state)780 static void test_dsdb_audit_get_unique_session_token(void **state)
781 {
782 struct ldb_context *ldb = NULL;
783 struct ldb_module *module = NULL;
784 struct auth_session_info *sess = NULL;
785 const struct GUID *guid;
786 const char * const GUID_S = "7130cb06-2062-6a1b-409e-3514c26b1773";
787 struct GUID in;
788 char *guid_str;
789 struct GUID_txt_buf guid_buff;
790
791
792 TALLOC_CTX *ctx = talloc_new(NULL);
793
794 ldb = ldb_init(ctx, NULL);
795 module = talloc_zero(ctx, struct ldb_module);
796 module->ldb = ldb;
797
798 /*
799 * Test a freshly initialized ldb
800 * should return NULL
801 */
802 guid = dsdb_audit_get_unique_session_token(module);
803 assert_null(guid);
804
805 /*
806 * Now add a NULL session info
807 */
808 ldb_set_opaque(ldb, DSDB_SESSION_INFO, NULL);
809 guid = dsdb_audit_get_unique_session_token(module);
810 assert_null(guid);
811
812 /*
813 * Now add a session info with no session id
814 * Note if the memory has not been zeroed correctly all bets are
815 * probably off.
816 */
817 sess = talloc_zero(ctx, struct auth_session_info);
818 ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
819 guid = dsdb_audit_get_unique_session_token(module);
820 /*
821 * We will get a GUID, but it's contents will be undefined
822 */
823 assert_non_null(guid);
824
825 /*
826 * Now set the session id and confirm that we get it back.
827 */
828 GUID_from_string(GUID_S, &in);
829 sess->unique_session_token = in;
830 guid = dsdb_audit_get_unique_session_token(module);
831 assert_non_null(guid);
832 guid_str = GUID_buf_string(guid, &guid_buff);
833 assert_string_equal(GUID_S, guid_str);
834
835 TALLOC_FREE(ctx);
836
837 }
838
test_dsdb_audit_get_actual_unique_session_token(void ** state)839 static void test_dsdb_audit_get_actual_unique_session_token(void **state)
840 {
841 struct ldb_context *ldb = NULL;
842 struct auth_session_info *sess = NULL;
843 const struct GUID *guid;
844 const char * const GUID_S = "7130cb06-2062-6a1b-409e-3514c26b1773";
845 struct GUID in;
846 char *guid_str;
847 struct GUID_txt_buf guid_buff;
848
849
850 TALLOC_CTX *ctx = talloc_new(NULL);
851
852 ldb = ldb_init(ctx, NULL);
853
854 /*
855 * Test a freshly initialized ldb
856 * should return NULL
857 */
858 guid = dsdb_audit_get_actual_unique_session_token(ldb);
859 assert_null(guid);
860
861 /*
862 * Now add a NULL session info
863 */
864 ldb_set_opaque(ldb, DSDB_NETWORK_SESSION_INFO, NULL);
865 guid = dsdb_audit_get_actual_unique_session_token(ldb);
866 assert_null(guid);
867
868 /*
869 * Now add a session info with no session id
870 * Note if the memory has not been zeroed correctly all bets are
871 * probably off.
872 */
873 sess = talloc_zero(ctx, struct auth_session_info);
874 ldb_set_opaque(ldb, DSDB_NETWORK_SESSION_INFO, sess);
875 guid = dsdb_audit_get_actual_unique_session_token(ldb);
876 /*
877 * We will get a GUID, but it's contents will be undefined
878 */
879 assert_non_null(guid);
880
881 /*
882 * Now set the session id and confirm that we get it back.
883 */
884 GUID_from_string(GUID_S, &in);
885 sess->unique_session_token = in;
886 guid = dsdb_audit_get_actual_unique_session_token(ldb);
887 assert_non_null(guid);
888 guid_str = GUID_buf_string(guid, &guid_buff);
889 assert_string_equal(GUID_S, guid_str);
890
891 TALLOC_FREE(ctx);
892
893 }
894
test_dsdb_audit_get_remote_host(void ** state)895 static void test_dsdb_audit_get_remote_host(void **state)
896 {
897 struct ldb_context *ldb = NULL;
898 char *rh = NULL;
899 struct tsocket_address *in = NULL;
900
901 TALLOC_CTX *ctx = talloc_new(NULL);
902
903 ldb = ldb_init(ctx, NULL);
904
905 /*
906 * Test a freshly initialized ldb
907 * should return "Unknown"
908 */
909 rh = dsdb_audit_get_remote_host(ldb, ctx);
910 assert_string_equal("Unknown", rh);
911 TALLOC_FREE(rh);
912
913 /*
914 * opaque set to null, should return NULL
915 */
916 ldb_set_opaque(ldb, "remoteAddress", NULL);
917 rh = dsdb_audit_get_remote_host(ldb, ctx);
918 assert_string_equal("Unknown", rh);
919 TALLOC_FREE(rh);
920
921 /*
922 * Ensure that the value set is returned
923 */
924 tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 42, &in);
925 ldb_set_opaque(ldb, "remoteAddress", in);
926 rh = dsdb_audit_get_remote_host(ldb, ctx);
927 assert_string_equal("ipv4:127.0.0.1:42", rh);
928 TALLOC_FREE(rh);
929
930 TALLOC_FREE(ctx);
931
932 }
933
test_dsdb_audit_get_primary_dn(void ** state)934 static void test_dsdb_audit_get_primary_dn(void **state)
935 {
936 struct ldb_request *req = NULL;
937 struct ldb_message *msg = NULL;
938 struct ldb_context *ldb = NULL;
939
940 struct ldb_dn *dn = NULL;
941
942 const char * const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
943 const char *s = NULL;
944
945 TALLOC_CTX *ctx = talloc_new(NULL);
946
947 req = talloc_zero(ctx, struct ldb_request);
948 msg = talloc_zero(ctx, struct ldb_message);
949 ldb = ldb_init(ctx, NULL);
950 dn = ldb_dn_new(ctx, ldb, DN);
951
952 /*
953 * Try an empty request.
954 */
955 s = dsdb_audit_get_primary_dn(req);
956 assert_null(s);
957
958 /*
959 * Now try an add with a null message.
960 */
961 req->operation = LDB_ADD;
962 req->op.add.message = NULL;
963 s = dsdb_audit_get_primary_dn(req);
964 assert_null(s);
965
966 /*
967 * Now try an mod with a null message.
968 */
969 req->operation = LDB_MODIFY;
970 req->op.mod.message = NULL;
971 s = dsdb_audit_get_primary_dn(req);
972 assert_null(s);
973
974 /*
975 * Now try an add with a missing dn
976 */
977 req->operation = LDB_ADD;
978 req->op.add.message = msg;
979 s = dsdb_audit_get_primary_dn(req);
980 assert_null(s);
981
982 /*
983 * Now try a mod with a messing dn
984 */
985 req->operation = LDB_ADD;
986 req->op.mod.message = msg;
987 s = dsdb_audit_get_primary_dn(req);
988 assert_null(s);
989
990 /*
991 * Add a dn to the message
992 */
993 msg->dn = dn;
994
995 /*
996 * Now try an add with a dn
997 */
998 req->operation = LDB_ADD;
999 req->op.add.message = msg;
1000 s = dsdb_audit_get_primary_dn(req);
1001 assert_non_null(s);
1002 assert_string_equal(DN, s);
1003
1004 /*
1005 * Now try a mod with a dn
1006 */
1007 req->operation = LDB_MODIFY;
1008 req->op.mod.message = msg;
1009 s = dsdb_audit_get_primary_dn(req);
1010 assert_non_null(s);
1011 assert_string_equal(DN, s);
1012
1013 /*
1014 * Try a delete without a dn
1015 */
1016 req->operation = LDB_DELETE;
1017 req->op.del.dn = NULL;
1018 s = dsdb_audit_get_primary_dn(req);
1019 assert_null(s);
1020
1021 /*
1022 * Try a delete with a dn
1023 */
1024 req->operation = LDB_DELETE;
1025 req->op.del.dn = dn;
1026 s = dsdb_audit_get_primary_dn(req);
1027 assert_non_null(s);
1028 assert_string_equal(DN, s);
1029
1030 /*
1031 * Try a rename without a dn
1032 */
1033 req->operation = LDB_RENAME;
1034 req->op.rename.olddn = NULL;
1035 s = dsdb_audit_get_primary_dn(req);
1036 assert_null(s);
1037
1038 /*
1039 * Try a rename with a dn
1040 */
1041 req->operation = LDB_RENAME;
1042 req->op.rename.olddn = dn;
1043 s = dsdb_audit_get_primary_dn(req);
1044 assert_non_null(s);
1045 assert_string_equal(DN, s);
1046
1047 /*
1048 * Try an extended operation, i.e. one that does not have a DN
1049 * associated with it for logging purposes.
1050 */
1051 req->operation = LDB_EXTENDED;
1052 s = dsdb_audit_get_primary_dn(req);
1053 assert_null(s);
1054
1055 TALLOC_FREE(ctx);
1056 }
1057
test_dsdb_audit_get_message(void ** state)1058 static void test_dsdb_audit_get_message(void **state)
1059 {
1060 struct ldb_request *req = NULL;
1061 struct ldb_message *msg = NULL;
1062 const struct ldb_message *r = NULL;
1063
1064
1065 TALLOC_CTX *ctx = talloc_new(NULL);
1066
1067 req = talloc_zero(ctx, struct ldb_request);
1068 msg = talloc_zero(ctx, struct ldb_message);
1069
1070 /*
1071 * Test an empty message
1072 */
1073 r = dsdb_audit_get_message(req);
1074 assert_null(r);
1075
1076 /*
1077 * Test an add message
1078 */
1079 req->operation = LDB_ADD;
1080 req->op.add.message = msg;
1081 r = dsdb_audit_get_message(req);
1082 assert_ptr_equal(msg, r);
1083
1084 /*
1085 * Test a modify message
1086 */
1087 req->operation = LDB_MODIFY;
1088 req->op.mod.message = msg;
1089 r = dsdb_audit_get_message(req);
1090 assert_ptr_equal(msg, r);
1091
1092 /*
1093 * Test a Delete message, i.e. trigger the default case
1094 */
1095 req->operation = LDB_DELETE;
1096 r = dsdb_audit_get_message(req);
1097 assert_null(r);
1098
1099 TALLOC_FREE(ctx);
1100 }
1101
test_dsdb_audit_get_secondary_dn(void ** state)1102 static void test_dsdb_audit_get_secondary_dn(void **state)
1103 {
1104 struct ldb_request *req = NULL;
1105 struct ldb_context *ldb = NULL;
1106
1107 struct ldb_dn *dn = NULL;
1108
1109 const char * const DN = "dn=CN=USER,CN=Users,DC=SAMBA,DC=ORG";
1110 const char *s = NULL;
1111
1112 TALLOC_CTX *ctx = talloc_new(NULL);
1113
1114 req = talloc_zero(ctx, struct ldb_request);
1115 ldb = ldb_init(ctx, NULL);
1116 dn = ldb_dn_new(ctx, ldb, DN);
1117
1118 /*
1119 * Try an empty request.
1120 */
1121 s = dsdb_audit_get_secondary_dn(req);
1122 assert_null(s);
1123
1124 /*
1125 * Try a rename without a dn
1126 */
1127 req->operation = LDB_RENAME;
1128 req->op.rename.newdn = NULL;
1129 s = dsdb_audit_get_secondary_dn(req);
1130 assert_null(s);
1131
1132 /*
1133 * Try a rename with a dn
1134 */
1135 req->operation = LDB_RENAME;
1136 req->op.rename.newdn = dn;
1137 s = dsdb_audit_get_secondary_dn(req);
1138 assert_non_null(s);
1139 assert_string_equal(DN, s);
1140
1141 /*
1142 * Try an extended operation, i.e. one that does not have a DN
1143 * associated with it for logging purposes.
1144 */
1145 req->operation = LDB_EXTENDED;
1146 s = dsdb_audit_get_primary_dn(req);
1147 assert_null(s);
1148
1149 TALLOC_FREE(ctx);
1150 }
1151
test_dsdb_audit_get_operation_name(void ** state)1152 static void test_dsdb_audit_get_operation_name(void **state)
1153 {
1154 struct ldb_request *req = NULL;
1155
1156 TALLOC_CTX *ctx = talloc_new(NULL);
1157
1158 req = talloc_zero(ctx, struct ldb_request);
1159
1160 req->operation = LDB_SEARCH;
1161 assert_string_equal("Search", dsdb_audit_get_operation_name(req));
1162
1163 req->operation = LDB_ADD;
1164 assert_string_equal("Add", dsdb_audit_get_operation_name(req));
1165
1166 req->operation = LDB_MODIFY;
1167 assert_string_equal("Modify", dsdb_audit_get_operation_name(req));
1168
1169 req->operation = LDB_DELETE;
1170 assert_string_equal("Delete", dsdb_audit_get_operation_name(req));
1171
1172 req->operation = LDB_RENAME;
1173 assert_string_equal("Rename", dsdb_audit_get_operation_name(req));
1174
1175 req->operation = LDB_EXTENDED;
1176 assert_string_equal("Extended", dsdb_audit_get_operation_name(req));
1177
1178 req->operation = LDB_REQ_REGISTER_CONTROL;
1179 assert_string_equal(
1180 "Register Control",
1181 dsdb_audit_get_operation_name(req));
1182
1183 req->operation = LDB_REQ_REGISTER_PARTITION;
1184 assert_string_equal(
1185 "Register Partition",
1186 dsdb_audit_get_operation_name(req));
1187
1188 /*
1189 * Trigger the default case
1190 */
1191 req->operation = -1;
1192 assert_string_equal("Unknown", dsdb_audit_get_operation_name(req));
1193
1194 TALLOC_FREE(ctx);
1195 }
1196
test_dsdb_audit_get_modification_action(void ** state)1197 static void test_dsdb_audit_get_modification_action(void **state)
1198 {
1199 assert_string_equal(
1200 "add",
1201 dsdb_audit_get_modification_action(LDB_FLAG_MOD_ADD));
1202 assert_string_equal(
1203 "delete",
1204 dsdb_audit_get_modification_action(LDB_FLAG_MOD_DELETE));
1205 assert_string_equal(
1206 "replace",
1207 dsdb_audit_get_modification_action(LDB_FLAG_MOD_REPLACE));
1208 /*
1209 * Trigger the default case
1210 */
1211 assert_string_equal(
1212 "unknown",
1213 dsdb_audit_get_modification_action(0));
1214 }
1215
test_dsdb_audit_is_password_attribute(void ** state)1216 static void test_dsdb_audit_is_password_attribute(void **state)
1217 {
1218 assert_true(dsdb_audit_is_password_attribute("userPassword"));
1219 assert_true(dsdb_audit_is_password_attribute("clearTextPassword"));
1220 assert_true(dsdb_audit_is_password_attribute("unicodePwd"));
1221 assert_true(dsdb_audit_is_password_attribute("dBCSPwd"));
1222
1223 assert_false(dsdb_audit_is_password_attribute("xserPassword"));
1224 }
1225
test_dsdb_audit_redact_attribute(void ** state)1226 static void test_dsdb_audit_redact_attribute(void **state)
1227 {
1228 assert_true(dsdb_audit_redact_attribute("userPassword"));
1229
1230 assert_true(dsdb_audit_redact_attribute("pekList"));
1231 assert_true(dsdb_audit_redact_attribute("clearTextPassword"));
1232 assert_true(dsdb_audit_redact_attribute("initialAuthIncoming"));
1233
1234 assert_false(dsdb_audit_redact_attribute("supaskrt"));
1235 }
1236
main(void)1237 int main(void) {
1238 const struct CMUnitTest tests[] = {
1239 cmocka_unit_test(test_dsdb_audit_add_ldb_value),
1240 cmocka_unit_test(test_dsdb_audit_attributes_json),
1241 cmocka_unit_test(test_dsdb_audit_get_remote_address),
1242 cmocka_unit_test(test_dsdb_audit_get_ldb_error_string),
1243 cmocka_unit_test(test_dsdb_audit_get_user_sid),
1244 cmocka_unit_test(test_dsdb_audit_get_actual_sid),
1245 cmocka_unit_test(test_dsdb_audit_is_system_session),
1246 cmocka_unit_test(test_dsdb_audit_get_unique_session_token),
1247 cmocka_unit_test(test_dsdb_audit_get_actual_unique_session_token),
1248 cmocka_unit_test(test_dsdb_audit_get_remote_host),
1249 cmocka_unit_test(test_dsdb_audit_get_primary_dn),
1250 cmocka_unit_test(test_dsdb_audit_get_message),
1251 cmocka_unit_test(test_dsdb_audit_get_secondary_dn),
1252 cmocka_unit_test(test_dsdb_audit_get_operation_name),
1253 cmocka_unit_test(test_dsdb_audit_get_modification_action),
1254 cmocka_unit_test(test_dsdb_audit_is_password_attribute),
1255 cmocka_unit_test(test_dsdb_audit_redact_attribute),
1256 };
1257
1258 cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
1259 return cmocka_run_group_tests(tests, NULL, NULL);
1260 }
1261