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