dsdb: Use customary variable names for audit event contexts
[metze/samba/wip.git] / source4 / dsdb / samdb / ldb_modules / audit_log.c
1 /*
2    ldb database library
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 /*
21  * Provide an audit log of changes made to the database and at a
22  * higher level details of any password changes and resets.
23  *
24  */
25
26 #include "includes.h"
27 #include "ldb_module.h"
28 #include "lib/audit_logging/audit_logging.h"
29
30 #include "dsdb/samdb/samdb.h"
31 #include "dsdb/samdb/ldb_modules/util.h"
32 #include "dsdb/samdb/ldb_modules/audit_util_proto.h"
33 #include "libcli/security/dom_sid.h"
34 #include "auth/common_auth.h"
35 #include "param/param.h"
36
37 #define OPERATION_JSON_TYPE "dsdbChange"
38 #define OPERATION_HR_TAG "DSDB Change"
39 #define OPERATION_MAJOR 1
40 #define OPERATION_MINOR 0
41 #define OPERATION_LOG_LVL 5
42
43 #define PASSWORD_JSON_TYPE "passwordChange"
44 #define PASSWORD_HR_TAG "Password Change"
45 #define PASSWORD_MAJOR 1
46 #define PASSWORD_MINOR 0
47 #define PASSWORD_LOG_LVL 5
48
49 #define TRANSACTION_JSON_TYPE "dsdbTransaction"
50 #define TRANSACTION_HR_TAG "DSDB Transaction"
51 #define TRANSACTION_MAJOR 1
52 #define TRANSACTION_MINOR 0
53 #define TRANSACTION_LOG_FAILURE_LVL 5
54 #define TRANSACTION_LOG_COMPLETION_LVL 10
55
56 #define REPLICATION_JSON_TYPE "replicatedUpdate"
57 #define REPLICATION_HR_TAG "Replicated Update"
58 #define REPLICATION_MAJOR 1
59 #define REPLICATION_MINOR 0
60 #define REPLICATION_LOG_LVL 5
61 /*
62  * Attribute values are truncated in the logs if they are longer than
63  * MAX_LENGTH
64  */
65 #define MAX_LENGTH 1024
66
67 #define min(a, b) (((a)>(b))?(b):(a))
68
69 /*
70  * Private data for the module, stored in the ldb_module private data
71  */
72 struct audit_context {
73         /*
74          * Should details of database operations be sent over the
75          * messaging bus.
76          */
77         bool send_samdb_events;
78         /*
79          * Should details of password changes and resets be sent over
80          * the messaging bus.
81          */
82         bool send_password_events;
83         /*
84          * The messaging context to send the messages over.  Will only
85          * be set if send_samdb_events or send_password_events are
86          * true.
87          */
88         struct imessaging_context *msg_ctx;
89         /*
90          * Unique transaction id for the current transaction
91          */
92         struct GUID transaction_guid;
93         /*
94          * Transaction start time, used to calculate the transaction
95          * duration.
96          */
97         struct timeval transaction_start;
98 };
99
100 /*
101  * @brief Has the password changed.
102  *
103  * Does the message contain a change to one of the password attributes? The
104  * password attributes are defined in DSDB_PASSWORD_ATTRIBUTES
105  *
106  * @return true if the message contains a password attribute
107  *
108  */
109 static bool has_password_changed(const struct ldb_message *message)
110 {
111         int i;
112         if (message == NULL) {
113                 return false;
114         }
115         for (i=0;i<message->num_elements;i++) {
116                 if (dsdb_audit_is_password_attribute(
117                         message->elements[i].name)) {
118                         return true;
119                 }
120         }
121         return false;
122 }
123
124 /*
125  * @brief Is the request a password "Change" or a "Reset"
126  *
127  * Get a description of the action being performed on the user password.  This
128  * routine assumes that the request contains password attributes and that the
129  * password ACL checks have been performed by acl.c
130  *
131  * @param request the ldb_request to inspect
132  * @param reply the ldb_reply, will contain the password controls
133  *
134  * @return "Change" if the password is being changed.
135  *         "Reset"  if the password is being reset.
136  */
137 static const char *get_password_action(
138         const struct ldb_request *request,
139         const struct ldb_reply *reply)
140 {
141         if(request->operation == LDB_ADD) {
142                 return "Reset";
143         } else {
144                 struct ldb_control *pav_ctrl = NULL;
145                 struct dsdb_control_password_acl_validation *pav = NULL;
146
147                 pav_ctrl = ldb_reply_get_control(
148                         discard_const(reply),
149                         DSDB_CONTROL_PASSWORD_ACL_VALIDATION_OID);
150                 if (pav_ctrl == NULL) {
151                         return "Reset";
152                 }
153
154                 pav = talloc_get_type_abort(
155                         pav_ctrl->data,
156                         struct dsdb_control_password_acl_validation);
157
158                 if (pav->pwd_reset) {
159                         return "Reset";
160                 } else {
161                         return "Change";
162                 }
163         }
164 }
165
166
167 #ifdef HAVE_JANSSON
168 /*
169  * @brief generate a JSON object detailing an ldb operation.
170  *
171  * Generate a JSON object detailing an ldb operation.
172  *
173  * @param module the ldb module
174  * @param request the request
175  * @param reply the result of the operation.
176  *
177  * @return the generated JSON object, should be freed with json_free.
178  *
179  */
180 static struct json_object operation_json(
181         struct ldb_module *module,
182         const struct ldb_request *request,
183         const struct ldb_reply *reply)
184 {
185         struct ldb_context *ldb = NULL;
186         const struct dom_sid *sid = NULL;
187         bool as_system = false;
188         struct json_object wrapper;
189         struct json_object audit;
190         const struct tsocket_address *remote = NULL;
191         const char *dn = NULL;
192         const char* operation = NULL;
193         const struct GUID *unique_session_token = NULL;
194         const struct ldb_message *message = NULL;
195         struct audit_context *ac = talloc_get_type(
196                 ldb_module_get_private(module),
197                 struct audit_context);
198
199         ldb = ldb_module_get_ctx(module);
200
201         remote = dsdb_audit_get_remote_address(ldb);
202         if (remote != NULL && dsdb_audit_is_system_session(module)) {
203                 as_system = true;
204                 sid = dsdb_audit_get_actual_sid(ldb);
205                 unique_session_token =
206                         dsdb_audit_get_actual_unique_session_token(ldb);
207         } else {
208                 sid = dsdb_audit_get_user_sid(module);
209                 unique_session_token =
210                         dsdb_audit_get_unique_session_token(module);
211         }
212         dn = dsdb_audit_get_primary_dn(request);
213         operation = dsdb_audit_get_operation_name(request);
214
215         audit = json_new_object();
216         json_add_version(&audit, OPERATION_MAJOR, OPERATION_MINOR);
217         json_add_int(&audit, "statusCode", reply->error);
218         json_add_string(&audit, "status", ldb_strerror(reply->error));
219         json_add_string(&audit, "operation", operation);
220         json_add_address(&audit, "remoteAddress", remote);
221         json_add_bool(&audit, "performedAsSystem", as_system);
222         json_add_sid(&audit, "userSid", sid);
223         json_add_string(&audit, "dn", dn);
224         json_add_guid(&audit, "transactionId", &ac->transaction_guid);
225         json_add_guid(&audit, "sessionId", unique_session_token);
226
227         message = dsdb_audit_get_message(request);
228         if (message != NULL) {
229                 struct json_object attributes =
230                         dsdb_audit_attributes_json(
231                                 request->operation,
232                                 message);
233                 json_add_object(&audit, "attributes", &attributes);
234         }
235
236         wrapper = json_new_object();
237         json_add_timestamp(&wrapper);
238         json_add_string(&wrapper, "type", OPERATION_JSON_TYPE);
239         json_add_object(&wrapper, OPERATION_JSON_TYPE, &audit);
240         return wrapper;
241 }
242
243 /*
244  * @brief generate a JSON object detailing a replicated update.
245  *
246  * Generate a JSON object detailing a replicated update
247  *
248  * @param module the ldb module
249  * @param request the request
250  * @paran reply the result of the operation
251  *
252  * @return the generated JSON object, should be freed with json_free.
253  *
254  */
255 static struct json_object replicated_update_json(
256         struct ldb_module *module,
257         const struct ldb_request *request,
258         const struct ldb_reply *reply)
259 {
260         struct json_object wrapper;
261         struct json_object audit;
262         struct audit_context *ac = talloc_get_type(
263                 ldb_module_get_private(module),
264                 struct audit_context);
265         struct dsdb_extended_replicated_objects *ro = talloc_get_type(
266                 request->op.extended.data,
267                 struct dsdb_extended_replicated_objects);
268         const char *partition_dn = NULL;
269         const char *error = NULL;
270
271         partition_dn = ldb_dn_get_linearized(ro->partition_dn);
272         error = get_friendly_werror_msg(ro->error);
273
274         audit = json_new_object();
275         json_add_version(&audit, REPLICATION_MAJOR, REPLICATION_MINOR);
276         json_add_int(&audit, "statusCode", reply->error);
277         json_add_string(&audit, "status", ldb_strerror(reply->error));
278         json_add_guid(&audit, "transactionId", &ac->transaction_guid);
279         json_add_int(&audit, "objectCount", ro->num_objects);
280         json_add_int(&audit, "linkCount", ro->linked_attributes_count);
281         json_add_string(&audit, "partitionDN", partition_dn);
282         json_add_string(&audit, "error", error);
283         json_add_int(&audit, "errorCode", W_ERROR_V(ro->error));
284         json_add_guid(
285                 &audit,
286                 "sourceDsa",
287                 &ro->source_dsa->source_dsa_obj_guid);
288         json_add_guid(
289                 &audit,
290                 "invocationId",
291                 &ro->source_dsa->source_dsa_invocation_id);
292
293         wrapper = json_new_object();
294         json_add_timestamp(&wrapper);
295         json_add_string(&wrapper, "type", REPLICATION_JSON_TYPE);
296         json_add_object(&wrapper, REPLICATION_JSON_TYPE, &audit);
297         return wrapper;
298 }
299
300 /*
301  * @brief generate a JSON object detailing a password change.
302  *
303  * Generate a JSON object detailing a password change.
304  *
305  * @param module the ldb module
306  * @param request the request
307  * @param reply the result/response
308  * @param status the status code returned for the underlying ldb operation.
309  *
310  * @return the generated JSON object.
311  *
312  */
313 static struct json_object password_change_json(
314         struct ldb_module *module,
315         const struct ldb_request *request,
316         const struct ldb_reply *reply)
317 {
318         struct ldb_context *ldb = NULL;
319         const struct dom_sid *sid = NULL;
320         const char* dn = NULL;
321         struct json_object wrapper;
322         struct json_object audit;
323         const struct tsocket_address *remote = NULL;
324         const char* action = NULL;
325         const struct GUID *unique_session_token = NULL;
326         struct audit_context *ac = talloc_get_type(
327                 ldb_module_get_private(module),
328                 struct audit_context);
329
330
331         ldb = ldb_module_get_ctx(module);
332
333         remote = dsdb_audit_get_remote_address(ldb);
334         sid = dsdb_audit_get_user_sid(module);
335         dn = dsdb_audit_get_primary_dn(request);
336         action = get_password_action(request, reply);
337         unique_session_token = dsdb_audit_get_unique_session_token(module);
338
339         audit = json_new_object();
340         json_add_version(&audit, PASSWORD_MAJOR, PASSWORD_MINOR);
341         json_add_int(&audit, "statusCode", reply->error);
342         json_add_string(&audit, "status", ldb_strerror(reply->error));
343         json_add_address(&audit, "remoteAddress", remote);
344         json_add_sid(&audit, "userSid", sid);
345         json_add_string(&audit, "dn", dn);
346         json_add_string(&audit, "action", action);
347         json_add_guid(&audit, "transactionId", &ac->transaction_guid);
348         json_add_guid(&audit, "sessionId", unique_session_token);
349
350         wrapper = json_new_object();
351         json_add_timestamp(&wrapper);
352         json_add_string(&wrapper, "type", PASSWORD_JSON_TYPE);
353         json_add_object(&wrapper, PASSWORD_JSON_TYPE, &audit);
354
355         return wrapper;
356 }
357
358
359 /*
360  * @brief create a JSON object containing details of a transaction event.
361  *
362  * Create a JSON object detailing a transaction transaction life cycle events,
363  * i.e. begin, commit, roll back
364  *
365  * @param action a one word description of the event/action
366  * @param transaction_id the GUID identifying the current transaction.
367  * @param status the status code returned by the operation
368  * @param duration the duration of the operation.
369  *
370  * @return a JSON object detailing the event
371  */
372 static struct json_object transaction_json(
373         const char *action,
374         struct GUID *transaction_id,
375         const int64_t duration)
376 {
377         struct json_object wrapper;
378         struct json_object audit;
379
380         audit = json_new_object();
381         json_add_version(&audit, TRANSACTION_MAJOR, TRANSACTION_MINOR);
382         json_add_string(&audit, "action", action);
383         json_add_guid(&audit, "transactionId", transaction_id);
384         json_add_int(&audit, "duration", duration);
385
386
387         wrapper = json_new_object();
388         json_add_timestamp(&wrapper);
389         json_add_string(&wrapper, "type", TRANSACTION_JSON_TYPE);
390         json_add_object(&wrapper, TRANSACTION_JSON_TYPE, &audit);
391
392         return wrapper;
393 }
394
395
396 /*
397  * @brief generate a JSON object detailing a commit failure.
398  *
399  * Generate a JSON object containing details of a commit failure.
400  *
401  * @param action the commit action, "commit" or "prepare"
402  * @param status the status code returned by commit
403  * @param reason any extra failure information/reason available
404  * @param transaction_id the GUID identifying the current transaction.
405  */
406 static struct json_object commit_failure_json(
407         const char *action,
408         const int64_t duration,
409         int status,
410         const char *reason,
411         struct GUID *transaction_id)
412 {
413         struct json_object wrapper;
414         struct json_object audit;
415
416         audit = json_new_object();
417         json_add_version(&audit, TRANSACTION_MAJOR, TRANSACTION_MINOR);
418         json_add_string(&audit, "action", action);
419         json_add_guid(&audit, "transactionId", transaction_id);
420         json_add_int(&audit, "duration", duration);
421         json_add_int(&audit, "statusCode", status);
422         json_add_string(&audit, "status", ldb_strerror(status));
423         json_add_string(&audit, "reason", reason);
424
425         wrapper = json_new_object();
426         json_add_timestamp(&wrapper);
427         json_add_string(&wrapper, "type", TRANSACTION_JSON_TYPE);
428         json_add_object(&wrapper, TRANSACTION_JSON_TYPE, &audit);
429
430         return wrapper;
431 }
432
433 #endif
434 /*
435  * @brief Print a human readable log line for a password change event.
436  *
437  * Generate a human readable log line detailing a password change.
438  *
439  * @param mem_ctx The talloc context that will own the generated log line.
440  * @param module the ldb module
441  * @param request the request
442  * @param reply the result/response
443  * @param status the status code returned for the underlying ldb operation.
444  *
445  * @return the generated log line.
446  */
447 static char *password_change_human_readable(
448         TALLOC_CTX *mem_ctx,
449         struct ldb_module *module,
450         const struct ldb_request *request,
451         const struct ldb_reply *reply)
452 {
453         struct ldb_context *ldb = NULL;
454         const char *remote_host = NULL;
455         const struct dom_sid *sid = NULL;
456         const char *user_sid = NULL;
457         const char *timestamp = NULL;
458         char *log_entry = NULL;
459         const char *action = NULL;
460         const char *dn = NULL;
461
462         TALLOC_CTX *ctx = talloc_new(NULL);
463
464         ldb = ldb_module_get_ctx(module);
465
466         remote_host = dsdb_audit_get_remote_host(ldb, ctx);
467         sid = dsdb_audit_get_user_sid(module);
468         user_sid = dom_sid_string(ctx, sid);
469         timestamp = audit_get_timestamp(ctx);
470         action = get_password_action(request, reply);
471         dn = dsdb_audit_get_primary_dn(request);
472
473         log_entry = talloc_asprintf(
474                 mem_ctx,
475                 "[%s] at [%s] status [%s] "
476                 "remote host [%s] SID [%s] DN [%s]",
477                 action,
478                 timestamp,
479                 ldb_strerror(reply->error),
480                 remote_host,
481                 user_sid,
482                 dn);
483         TALLOC_FREE(ctx);
484         return log_entry;
485 }
486 /*
487  * @brief Generate a human readable string, detailing attributes in a message
488  *
489  * For modify operations each attribute is prefixed with the action.
490  * Normal values are enclosed in []
491  * Base64 values are enclosed in {}
492  * Truncated values are indicated by three trailing dots "..."
493  *
494  * @param ldb The ldb_context
495  * @param buffer The attributes will be appended to the buffer.
496  *               assumed to have been allocated via talloc.
497  * @param operation The operation type
498  * @param message the message to process
499  *
500  */
501 static char *log_attributes(
502         struct ldb_context *ldb,
503         char *buffer,
504         enum ldb_request_type operation,
505         const struct ldb_message *message)
506 {
507         int i, j;
508         for (i=0;i<message->num_elements;i++) {
509                 if (i > 0) {
510                         buffer = talloc_asprintf_append_buffer(buffer, " ");
511                 }
512
513                 if (message->elements[i].name == NULL) {
514                         ldb_debug(
515                                 ldb,
516                                 LDB_DEBUG_ERROR,
517                                 "Error: Invalid element name (NULL) at "
518                                 "position %d", i);
519                         return NULL;
520                 }
521
522                 if (operation == LDB_MODIFY) {
523                         const char *action =NULL;
524                         action = dsdb_audit_get_modification_action(
525                                 message->elements[i].flags);
526                         buffer = talloc_asprintf_append_buffer(
527                                 buffer,
528                                 "%s: %s ",
529                                 action,
530                                 message->elements[i].name);
531                 } else {
532                         buffer = talloc_asprintf_append_buffer(
533                                 buffer,
534                                 "%s ",
535                                 message->elements[i].name);
536                 }
537
538                 if (dsdb_audit_redact_attribute(message->elements[i].name)) {
539                         /*
540                          * Do not log the value of any secret or password
541                          * attributes
542                          */
543                         buffer = talloc_asprintf_append_buffer(
544                                 buffer,
545                                 "[REDACTED SECRET ATTRIBUTE]");
546                         continue;
547                 }
548
549                 for (j=0;j<message->elements[i].num_values;j++) {
550                         struct ldb_val v;
551                         bool use_b64_encode = false;
552                         int length;
553                         if (j > 0) {
554                                 buffer = talloc_asprintf_append_buffer(
555                                         buffer,
556                                         " ");
557                         }
558
559                         v = message->elements[i].values[j];
560                         length = min(MAX_LENGTH, v.length);
561                         use_b64_encode = ldb_should_b64_encode(ldb, &v);
562                         if (use_b64_encode) {
563                                 const char *encoded = ldb_base64_encode(
564                                         buffer,
565                                         (char *)v.data,
566                                         length);
567                                 buffer = talloc_asprintf_append_buffer(
568                                         buffer,
569                                         "{%s%s}",
570                                         encoded,
571                                         (v.length > MAX_LENGTH ? "..." : ""));
572                         } else {
573                                 buffer = talloc_asprintf_append_buffer(
574                                         buffer,
575                                         "[%*.*s%s]",
576                                         length,
577                                         length,
578                                         (char *)v.data,
579                                         (v.length > MAX_LENGTH ? "..." : ""));
580                         }
581                 }
582         }
583         return buffer;
584 }
585
586 /*
587  * @brief generate a human readable log entry detailing an ldb operation.
588  *
589  * Generate a human readable log entry detailing an ldb operation.
590  *
591  * @param mem_ctx The talloc context owning the returned string.
592  * @param module the ldb module
593  * @param request the request
594  * @param reply the result of the operation
595  *
596  * @return the log entry.
597  *
598  */
599 static char *operation_human_readable(
600         TALLOC_CTX *mem_ctx,
601         struct ldb_module *module,
602         const struct ldb_request *request,
603         const struct ldb_reply *reply)
604 {
605         struct ldb_context *ldb = NULL;
606         const char *remote_host = NULL;
607         const struct dom_sid *sid = NULL;
608         const char *user_sid = NULL;
609         const char *timestamp = NULL;
610         const char *op_name = NULL;
611         char *log_entry = NULL;
612         const char *dn = NULL;
613         const char *new_dn = NULL;
614         const struct ldb_message *message = NULL;
615
616         TALLOC_CTX *ctx = talloc_new(NULL);
617
618         ldb = ldb_module_get_ctx(module);
619
620         remote_host = dsdb_audit_get_remote_host(ldb, ctx);
621         if (remote_host != NULL && dsdb_audit_is_system_session(module)) {
622                 sid = dsdb_audit_get_actual_sid(ldb);
623         } else {
624                 sid = dsdb_audit_get_user_sid(module);
625         }
626         user_sid = dom_sid_string(ctx, sid);
627         timestamp = audit_get_timestamp(ctx);
628         op_name = dsdb_audit_get_operation_name(request);
629         dn = dsdb_audit_get_primary_dn(request);
630         new_dn = dsdb_audit_get_secondary_dn(request);
631
632         message = dsdb_audit_get_message(request);
633
634         log_entry = talloc_asprintf(
635                 mem_ctx,
636                 "[%s] at [%s] status [%s] "
637                 "remote host [%s] SID [%s] DN [%s]",
638                 op_name,
639                 timestamp,
640                 ldb_strerror(reply->error),
641                 remote_host,
642                 user_sid,
643                 dn);
644         if (new_dn != NULL) {
645                 log_entry = talloc_asprintf_append_buffer(
646                         log_entry,
647                         " New DN [%s]",
648                         new_dn);
649         }
650         if (message != NULL) {
651                 log_entry = talloc_asprintf_append_buffer(log_entry,
652                                                           " attributes [");
653                 log_entry = log_attributes(ldb,
654                                            log_entry,
655                                            request->operation,
656                                            message);
657                 log_entry = talloc_asprintf_append_buffer(log_entry, "]");
658         }
659         TALLOC_FREE(ctx);
660         return log_entry;
661 }
662
663 /*
664  * @brief generate a human readable log entry detailing a replicated update
665  *        operation.
666  *
667  * Generate a human readable log entry detailing a replicated update operation
668  *
669  * @param mem_ctx The talloc context owning the returned string.
670  * @param module the ldb module
671  * @param request the request
672  * @param reply the result of the operation.
673  *
674  * @return the log entry.
675  *
676  */
677 static char *replicated_update_human_readable(
678         TALLOC_CTX *mem_ctx,
679         struct ldb_module *module,
680         const struct ldb_request *request,
681         const struct ldb_reply *reply)
682 {
683         struct dsdb_extended_replicated_objects *ro = talloc_get_type(
684                 request->op.extended.data,
685                 struct dsdb_extended_replicated_objects);
686         const char *partition_dn = NULL;
687         const char *error = NULL;
688         char *log_entry = NULL;
689         char *timestamp = NULL;
690         struct GUID_txt_buf object_buf;
691         const char *object = NULL;
692         struct GUID_txt_buf invocation_buf;
693         const char *invocation = NULL;
694
695
696         TALLOC_CTX *ctx = talloc_new(NULL);
697
698         timestamp = audit_get_timestamp(ctx);
699         error = get_friendly_werror_msg(ro->error);
700         partition_dn = ldb_dn_get_linearized(ro->partition_dn);
701         object = GUID_buf_string(
702                 &ro->source_dsa->source_dsa_obj_guid,
703                 &object_buf);
704         invocation = GUID_buf_string(
705                 &ro->source_dsa->source_dsa_invocation_id,
706                 &invocation_buf);
707
708
709         log_entry = talloc_asprintf(
710                 mem_ctx,
711                 "at [%s] status [%s] error [%s] partition [%s] objects [%d] "
712                 "links [%d] object [%s] invocation [%s]",
713                 timestamp,
714                 ldb_strerror(reply->error),
715                 error,
716                 partition_dn,
717                 ro->num_objects,
718                 ro->linked_attributes_count,
719                 object,
720                 invocation);
721
722         TALLOC_FREE(ctx);
723         return log_entry;
724 }
725 /*
726  * @brief create a human readable log entry detailing a transaction event.
727  *
728  * Create a human readable log entry detailing a transaction event.
729  * i.e. begin, commit, roll back
730  *
731  * @param mem_ctx The talloc context owning the returned string.
732  * @param action a one word description of the event/action
733  * @param duration the duration of the transaction.
734  *
735  * @return the log entry
736  */
737 static char *transaction_human_readable(
738         TALLOC_CTX *mem_ctx,
739         const char* action,
740         const int64_t duration)
741 {
742         const char *timestamp = NULL;
743         char *log_entry = NULL;
744
745         TALLOC_CTX *ctx = talloc_new(NULL);
746
747         timestamp = audit_get_timestamp(ctx);
748
749         log_entry = talloc_asprintf(
750                 mem_ctx,
751                 "[%s] at [%s] duration [%ld]",
752                 action,
753                 timestamp,
754                 duration);
755
756         TALLOC_FREE(ctx);
757         return log_entry;
758 }
759
760 /*
761  * @brief generate a human readable log entry detailing a commit failure.
762  *
763  * Generate generate a human readable log entry detailing a commit failure.
764  *
765  * @param mem_ctx The talloc context owning the returned string.
766  * @param action the commit action, "prepare" or "commit"
767  * @param status the status code returned by commit
768  * @param reason any extra failure information/reason available
769  *
770  * @return the log entry
771  */
772 static char *commit_failure_human_readable(
773         TALLOC_CTX *mem_ctx,
774         const char *action,
775         const int64_t duration,
776         int status,
777         const char *reason)
778 {
779         const char *timestamp = NULL;
780         char *log_entry = NULL;
781
782         TALLOC_CTX *ctx = talloc_new(NULL);
783
784         timestamp = audit_get_timestamp(ctx);
785
786         log_entry = talloc_asprintf(
787                 mem_ctx,
788                 "[%s] at [%s] duration [%ld] status [%d] reason [%s]",
789                 action,
790                 timestamp,
791                 duration,
792                 status,
793                 reason);
794
795         TALLOC_FREE(ctx);
796         return log_entry;
797 }
798
799 /*
800  * @brief log details of a standard ldb operation.
801  *
802  * Log the details of an ldb operation in JSON and or human readable format
803  * and send over the message bus.
804  *
805  * @param module the ldb_module
806  * @param request the operation request.
807  * @param reply the operation result.
808  * @param the status code returned for the operation.
809  *
810  */
811 static void log_standard_operation(
812         struct ldb_module *module,
813         const struct ldb_request *request,
814         const struct ldb_reply *reply)
815 {
816
817         const struct ldb_message *message = dsdb_audit_get_message(request);
818         bool password_changed = has_password_changed(message);
819         struct audit_context *ac =
820                 talloc_get_type(ldb_module_get_private(module),
821                                 struct audit_context);
822
823         TALLOC_CTX *ctx = talloc_new(NULL);
824
825         if (CHECK_DEBUGLVLC(DBGC_DSDB_AUDIT, OPERATION_LOG_LVL)) {
826                 char *entry = NULL;
827                 entry = operation_human_readable(
828                         ctx,
829                         module,
830                         request,
831                         reply);
832                 audit_log_human_text(
833                         OPERATION_HR_TAG,
834                         entry,
835                         DBGC_DSDB_AUDIT,
836                         OPERATION_LOG_LVL);
837                 TALLOC_FREE(entry);
838         }
839         if (CHECK_DEBUGLVLC(DBGC_DSDB_PWD_AUDIT, PASSWORD_LOG_LVL)) {
840                 if (password_changed) {
841                         char *entry = NULL;
842                         entry = password_change_human_readable(
843                                 ctx,
844                                 module,
845                                 request,
846                                 reply);
847                         audit_log_human_text(
848                                 PASSWORD_HR_TAG,
849                                 entry,
850                                 DBGC_DSDB_PWD_AUDIT,
851                                 PASSWORD_LOG_LVL);
852                         TALLOC_FREE(entry);
853                 }
854         }
855 #ifdef HAVE_JANSSON
856         if (CHECK_DEBUGLVLC(DBGC_DSDB_AUDIT_JSON, OPERATION_LOG_LVL) ||
857                 (ac->msg_ctx && ac->send_samdb_events)) {
858                 struct json_object json;
859                 json = operation_json(module, request, reply);
860                 audit_log_json(
861                         OPERATION_JSON_TYPE,
862                         &json,
863                         DBGC_DSDB_AUDIT_JSON,
864                         OPERATION_LOG_LVL);
865                 if (ac->msg_ctx && ac->send_password_events) {
866                         audit_message_send(
867                                 ac->msg_ctx,
868                                 DSDB_EVENT_NAME,
869                                 MSG_DSDB_LOG,
870                                 &json);
871                 }
872                 json_free(&json);
873         }
874         if (CHECK_DEBUGLVLC(DBGC_DSDB_PWD_AUDIT_JSON, PASSWORD_LOG_LVL) ||
875                 (ac->msg_ctx && ac->send_password_events)) {
876                 if (password_changed) {
877                         struct json_object json;
878                         json = password_change_json(module, request, reply);
879                         audit_log_json(
880                                 PASSWORD_JSON_TYPE,
881                                 &json,
882                                 DBGC_DSDB_PWD_AUDIT_JSON,
883                                 PASSWORD_LOG_LVL);
884                         if (ac->send_password_events) {
885                                 audit_message_send(
886                                         ac->msg_ctx,
887                                         DSDB_PWD_EVENT_NAME,
888                                         MSG_DSDB_PWD_LOG,
889                                         &json);
890                         }
891                         json_free(&json);
892                 }
893         }
894 #endif
895         TALLOC_FREE(ctx);
896 }
897
898 /*
899  * @brief log details of a replicated update.
900  *
901  * Log the details of a replicated update in JSON and or human readable
902  * format and send over the message bus.
903  *
904  * @param module the ldb_module
905  * @param request the operation request
906  * @param reply the result of the operation.
907  *
908  */
909 static void log_replicated_operation(
910         struct ldb_module *module,
911         const struct ldb_request *request,
912         const struct ldb_reply *reply)
913 {
914
915         struct audit_context *ac =
916                 talloc_get_type(ldb_module_get_private(module),
917                                 struct audit_context);
918
919         TALLOC_CTX *ctx = talloc_new(NULL);
920
921         if (CHECK_DEBUGLVLC(DBGC_DSDB_AUDIT, REPLICATION_LOG_LVL)) {
922                 char *entry = NULL;
923                 entry = replicated_update_human_readable(
924                         ctx,
925                         module,
926                         request,
927                         reply);
928                 audit_log_human_text(
929                         REPLICATION_HR_TAG,
930                         entry,
931                         DBGC_DSDB_AUDIT,
932                         REPLICATION_LOG_LVL);
933                 TALLOC_FREE(entry);
934         }
935 #ifdef HAVE_JANSSON
936         if (CHECK_DEBUGLVLC(DBGC_DSDB_AUDIT_JSON, REPLICATION_LOG_LVL) ||
937                 (ac->msg_ctx && ac->send_samdb_events)) {
938                 struct json_object json;
939                 json = replicated_update_json(module, request, reply);
940                 audit_log_json(
941                         REPLICATION_JSON_TYPE,
942                         &json,
943                         DBGC_DSDB_AUDIT_JSON,
944                         REPLICATION_LOG_LVL);
945                 if (ac->send_samdb_events) {
946                         audit_message_send(
947                                 ac->msg_ctx,
948                                 DSDB_EVENT_NAME,
949                                 MSG_DSDB_LOG,
950                                 &json);
951                 }
952                 json_free(&json);
953         }
954 #endif
955         TALLOC_FREE(ctx);
956 }
957
958 /*
959  * @brief log details of an ldb operation.
960  *
961  * Log the details of an ldb operation in JSON and or human readable format
962  * and send over the message bus.
963  *
964  * @param module the ldb_module
965  * @param request the operation request
966  * @part reply the result of the operation
967  *
968  */
969 static void log_operation(
970         struct ldb_module *module,
971         const struct ldb_request *request,
972         const struct ldb_reply *reply)
973 {
974
975         if (request->operation == LDB_EXTENDED) {
976                 if (strcmp(
977                         request->op.extended.oid,
978                         DSDB_EXTENDED_REPLICATED_OBJECTS_OID) != 0) {
979
980                         log_replicated_operation(module, request, reply);
981                 }
982         } else {
983                 log_standard_operation(module, request, reply);
984         }
985 }
986
987 /*
988  * @brief log details of a transaction event.
989  *
990  * Log the details of a transaction event in JSON and or human readable format
991  * and send over the message bus.
992  *
993  * @param module the ldb_module
994  * @param action the transaction event i.e. begin, commit, roll back.
995  * @param log_level the logging level
996  *
997  */
998 static void log_transaction(
999         struct ldb_module *module,
1000         const char *action,
1001         int log_level)
1002 {
1003
1004         struct audit_context *ac =
1005                 talloc_get_type(ldb_module_get_private(module),
1006                                 struct audit_context);
1007         const struct timeval now = timeval_current();
1008         const int64_t duration = usec_time_diff(&now, &ac->transaction_start);
1009
1010         TALLOC_CTX *ctx = talloc_new(NULL);
1011
1012         if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT, log_level)) {
1013                 char* entry = NULL;
1014                 entry = transaction_human_readable(ctx, action, duration);
1015                 audit_log_human_text(
1016                         TRANSACTION_HR_TAG,
1017                         entry,
1018                         DBGC_DSDB_TXN_AUDIT,
1019                         log_level);
1020                 TALLOC_FREE(entry);
1021         }
1022 #ifdef HAVE_JANSSON
1023         if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT_JSON, log_level) ||
1024                 (ac->msg_ctx && ac->send_samdb_events)) {
1025                 struct json_object json;
1026                 json = transaction_json(
1027                         action,
1028                         &ac->transaction_guid,
1029                         duration);
1030                 audit_log_json(
1031                         TRANSACTION_JSON_TYPE,
1032                         &json,
1033                         DBGC_DSDB_TXN_AUDIT_JSON,
1034                         log_level);
1035                 if (ac->send_samdb_events) {
1036                         audit_message_send(
1037                                 ac->msg_ctx,
1038                                 DSDB_EVENT_NAME,
1039                                 MSG_DSDB_LOG,
1040                                 &json);
1041                 }
1042                 json_free(&json);
1043         }
1044 #endif
1045         TALLOC_FREE(ctx);
1046 }
1047
1048 /*
1049  * @brief log details of a commit failure.
1050  *
1051  * Log the details of a commit failure in JSON and or human readable
1052  * format and send over the message bus.
1053  *
1054  * @param module the ldb_module
1055  * @param action the commit action "prepare" or "commit"
1056  * @param status the ldb status code returned by prepare commit.
1057  *
1058  */
1059 static void log_commit_failure(
1060         struct ldb_module *module,
1061         const char *action,
1062         int status)
1063 {
1064
1065         struct audit_context *ac =
1066                 talloc_get_type(ldb_module_get_private(module),
1067                                 struct audit_context);
1068         const char* reason = dsdb_audit_get_ldb_error_string(module, status);
1069         const int log_level = TRANSACTION_LOG_FAILURE_LVL;
1070         const struct timeval now = timeval_current();
1071         const int64_t duration = usec_time_diff(&now, &ac->transaction_start);
1072
1073         TALLOC_CTX *ctx = talloc_new(NULL);
1074
1075         if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT, log_level)) {
1076
1077                 char* entry = NULL;
1078                 entry = commit_failure_human_readable(
1079                         ctx,
1080                         action,
1081                         duration,
1082                         status,
1083                         reason);
1084                 audit_log_human_text(
1085                         TRANSACTION_HR_TAG,
1086                         entry,
1087                         DBGC_DSDB_TXN_AUDIT,
1088                         TRANSACTION_LOG_FAILURE_LVL);
1089                 TALLOC_FREE(entry);
1090         }
1091 #ifdef HAVE_JANSSON
1092         if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT_JSON, log_level) ||
1093                 (ac->msg_ctx && ac->send_samdb_events)) {
1094                 struct json_object json;
1095                 json = commit_failure_json(
1096                         action,
1097                         duration,
1098                         status,
1099                         reason,
1100                         &ac->transaction_guid);
1101                 audit_log_json(
1102                         TRANSACTION_JSON_TYPE,
1103                         &json,
1104                         DBGC_DSDB_TXN_AUDIT_JSON,
1105                         log_level);
1106                 if (ac->send_samdb_events) {
1107                         audit_message_send(ac->msg_ctx,
1108                                            DSDB_EVENT_NAME,
1109                                            MSG_DSDB_LOG,
1110                                            &json);
1111                 }
1112                 json_free(&json);
1113         }
1114 #endif
1115         TALLOC_FREE(ctx);
1116 }
1117
1118 /*
1119  * Context needed by audit_callback
1120  */
1121 struct audit_callback_context {
1122         struct ldb_request *request;
1123         struct ldb_module *module;
1124 };
1125
1126 /*
1127  * @brief call back function for the ldb_operations.
1128  *
1129  * As the LDB operations are async, and we wish to examine the results of
1130  * the operations, a callback needs to be registered to process the results
1131  * of the LDB operations.
1132  *
1133  * @param req the ldb request
1134  * @param res the result of the operation
1135  *
1136  * @return the LDB_STATUS
1137  */
1138 static int audit_callback(struct ldb_request *req, struct ldb_reply *ares)
1139 {
1140         struct audit_callback_context *ac = NULL;
1141
1142         ac = talloc_get_type(
1143                 req->context,
1144                 struct audit_callback_context);
1145
1146         if (!ares) {
1147                 return ldb_module_done(
1148                         ac->request,
1149                         NULL,
1150                         NULL,
1151                         LDB_ERR_OPERATIONS_ERROR);
1152         }
1153
1154         /* pass on to the callback */
1155         switch (ares->type) {
1156         case LDB_REPLY_ENTRY:
1157                 return ldb_module_send_entry(
1158                         ac->request,
1159                         ares->message,
1160                         ares->controls);
1161
1162         case LDB_REPLY_REFERRAL:
1163                 return ldb_module_send_referral(
1164                         ac->request,
1165                         ares->referral);
1166
1167         case LDB_REPLY_DONE:
1168                 /*
1169                  * Log the operation once DONE
1170                  */
1171                 log_operation(ac->module, ac->request, ares);
1172                 return ldb_module_done(
1173                         ac->request,
1174                         ares->controls,
1175                         ares->response,
1176                         ares->error);
1177
1178         default:
1179                 /* Can't happen */
1180                 return LDB_ERR_OPERATIONS_ERROR;
1181         }
1182 }
1183
1184 /*
1185  * @brief Add the current transaction identifier to the request.
1186  *
1187  * Add the current transaction identifier in the module private data,
1188  * to the request as a control.
1189  *
1190  * @param module
1191  * @param req the request.
1192  *
1193  * @return an LDB_STATUS code, LDB_SUCCESS if successful.
1194  */
1195 static int add_transaction_id(
1196         struct ldb_module *module,
1197         struct ldb_request *req)
1198 {
1199         struct audit_context *ac =
1200                 talloc_get_type(ldb_module_get_private(module),
1201                                 struct audit_context);
1202         struct dsdb_control_transaction_identifier *transaction_id;
1203         int ret;
1204
1205         transaction_id = talloc_zero(
1206                 req,
1207                 struct dsdb_control_transaction_identifier);
1208         if (transaction_id == NULL) {
1209                 struct ldb_context *ldb = ldb_module_get_ctx(module);
1210                 return ldb_oom(ldb);
1211         }
1212         transaction_id->transaction_guid = ac->transaction_guid;
1213         ret = ldb_request_add_control(req,
1214                                       DSDB_CONTROL_TRANSACTION_IDENTIFIER_OID,
1215                                       false,
1216                                       transaction_id);
1217         return ret;
1218
1219 }
1220
1221 /*
1222  * @brief log details of an add operation.
1223  *
1224  * Log the details of an add operation.
1225  *
1226  * @param module the ldb_module
1227  * @param req the ldb_request
1228  *
1229  * @return ldb status code
1230  */
1231 static int log_add(
1232         struct ldb_module *module,
1233         struct ldb_request *req)
1234 {
1235         struct audit_callback_context *context = NULL;
1236         struct ldb_request *new_req = NULL;
1237         struct ldb_context *ldb = NULL;
1238         int ret;
1239
1240         ldb = ldb_module_get_ctx(module);
1241         context = talloc_zero(req, struct audit_callback_context);
1242
1243         if (context == NULL) {
1244                 return ldb_oom(ldb);
1245         }
1246         context->request = req;
1247         context->module  = module;
1248         /*
1249          * We want to log the return code status, so we need to register
1250          * a callback function to get the actual result.
1251          * We need to take a new copy so that we don't alter the callers copy
1252          */
1253         ret = ldb_build_add_req(
1254                 &new_req,
1255                 ldb,
1256                 req,
1257                 req->op.add.message,
1258                 req->controls,
1259                 context,
1260                 audit_callback,
1261                 req);
1262         if (ret != LDB_SUCCESS) {
1263                 return ret;
1264         }
1265         ret = add_transaction_id(module, new_req);
1266         if (ret != LDB_SUCCESS) {
1267                 return ret;
1268         }
1269         return ldb_next_request(module, new_req);
1270 }
1271
1272 /*
1273  * @brief log details of an delete operation.
1274  *
1275  * Log the details of an delete operation.
1276  *
1277  * @param module the ldb_module
1278  * @param req the ldb_request
1279  *
1280  * @return ldb status code
1281  */
1282 static int log_delete(
1283         struct ldb_module *module,
1284         struct ldb_request *req)
1285 {
1286         struct audit_callback_context *context = NULL;
1287         struct ldb_request *new_req = NULL;
1288         struct ldb_context *ldb = NULL;
1289         int ret;
1290
1291         ldb = ldb_module_get_ctx(module);
1292         context = talloc_zero(req, struct audit_callback_context);
1293
1294         if (context == NULL) {
1295                 return ldb_oom(ldb);
1296         }
1297         context->request = req;
1298         context->module  = module;
1299         /*
1300          * We want to log the return code status, so we need to register
1301          * a callback function to get the actual result.
1302          * We need to take a new copy so that we don't alter the callers copy
1303          */
1304         ret = ldb_build_del_req(&new_req,
1305                                 ldb,
1306                                 req,
1307                                 req->op.del.dn,
1308                                 req->controls,
1309                                 context,
1310                                 audit_callback,
1311                                 req);
1312         if (ret != LDB_SUCCESS) {
1313                 return ret;
1314         }
1315         ret = add_transaction_id(module, new_req);
1316         if (ret != LDB_SUCCESS) {
1317                 return ret;
1318         }
1319         return ldb_next_request(module, new_req);
1320 }
1321
1322 /*
1323  * @brief log details of a modify operation.
1324  *
1325  * Log the details of a modify operation.
1326  *
1327  * @param module the ldb_module
1328  * @param req the ldb_request
1329  *
1330  * @return ldb status code
1331  */
1332 static int log_modify(
1333         struct ldb_module *module,
1334         struct ldb_request *req)
1335 {
1336         struct audit_callback_context *context = NULL;
1337         struct ldb_request *new_req = NULL;
1338         struct ldb_context *ldb = NULL;
1339         int ret;
1340
1341         ldb = ldb_module_get_ctx(module);
1342         context = talloc_zero(req, struct audit_callback_context);
1343
1344         if (context == NULL) {
1345                 return ldb_oom(ldb);
1346         }
1347         context->request = req;
1348         context->module  = module;
1349         /*
1350          * We want to log the return code status, so we need to register
1351          * a callback function to get the actual result.
1352          * We need to take a new copy so that we don't alter the callers copy
1353          */
1354         ret = ldb_build_mod_req(
1355                 & new_req,
1356                 ldb,
1357                 req,
1358                 req->op.mod.message,
1359                 req->controls,
1360                 context,
1361                 audit_callback,
1362                 req);
1363         if (ret != LDB_SUCCESS) {
1364                 return ret;
1365         }
1366         ret = add_transaction_id(module, new_req);
1367         if (ret != LDB_SUCCESS) {
1368                 return ret;
1369         }
1370         return ldb_next_request(module, new_req);
1371 }
1372
1373 /*
1374  * @brief process a transaction start.
1375  *
1376  * process a transaction start, as we don't currently log transaction starts
1377  * just generate the new transaction_id.
1378  *
1379  * @param module the ldb_module
1380  * @param req the ldb_request
1381  *
1382  * @return ldb status code
1383  */
1384 static int log_start_transaction(struct ldb_module *module)
1385 {
1386         struct audit_context *ac =
1387                 talloc_get_type(ldb_module_get_private(module),
1388                                 struct audit_context);
1389
1390         /*
1391          * We do not log transaction begins
1392          * however we do generate a new transaction_id and record the start
1393          * time so that we can log the transaction duration.
1394          *
1395          */
1396         ac->transaction_guid = GUID_random();
1397         ac->transaction_start = timeval_current();
1398         return ldb_next_start_trans(module);
1399 }
1400
1401 /*
1402  * @brief log details of a prepare commit.
1403  *
1404  * Log the details of a prepare commit, currently only details of
1405  * failures are logged.
1406  *
1407  * @param module the ldb_module
1408  * @param req the ldb_request
1409  *
1410  * @return ldb status code
1411  */
1412 static int log_prepare_commit(struct ldb_module *module)
1413 {
1414
1415         int ret = ldb_next_prepare_commit(module);
1416         if (ret != LDB_SUCCESS) {
1417                 /*
1418                  * We currently only log prepare commit failures
1419                  */
1420                 log_commit_failure(module, "prepare", ret);
1421         }
1422         return ret;
1423 }
1424
1425 /*
1426  * @brief process a transaction end aka commit.
1427  *
1428  * process a transaction end, as we don't currently log transaction ends
1429  * just clear transaction_id.
1430  *
1431  * @param module the ldb_module
1432  * @param req the ldb_request
1433  *
1434  * @return ldb status code
1435  */
1436 static int log_end_transaction(struct ldb_module *module)
1437 {
1438         struct audit_context *ac =
1439                 talloc_get_type(ldb_module_get_private(module),
1440                                 struct audit_context);
1441         int ret = 0;
1442
1443
1444         ret = ldb_next_end_trans(module);
1445         if (ret == LDB_SUCCESS) {
1446                 log_transaction(
1447                         module,
1448                         "commit",
1449                         TRANSACTION_LOG_COMPLETION_LVL);
1450         } else {
1451                 log_commit_failure(module, "commit", ret);
1452         }
1453         /*
1454          * Clear the transaction id inserted by log_start_transaction
1455          */
1456         memset(&ac->transaction_guid, 0, sizeof(struct GUID));
1457         return ret;
1458 }
1459
1460 /*
1461  * @brief log details of a transaction delete aka roll back.
1462  *
1463  * Log details of a transaction roll back.
1464  *
1465  * @param module the ldb_module
1466  * @param req the ldb_request
1467  *
1468  * @return ldb status code
1469  */
1470 static int log_del_transaction(struct ldb_module *module)
1471 {
1472         struct audit_context *ac =
1473                 talloc_get_type(ldb_module_get_private(module),
1474                                 struct audit_context);
1475
1476         log_transaction(module, "rollback", TRANSACTION_LOG_FAILURE_LVL);
1477         memset(&ac->transaction_guid, 0, sizeof(struct GUID));
1478         return ldb_next_del_trans(module);
1479 }
1480
1481 /*
1482  * @brief log details of an extended operation.
1483  *
1484  * Log the details of an extended operation.
1485  *
1486  * @param module the ldb_module
1487  * @param req the ldb_request
1488  *
1489  * @return ldb status code
1490  */
1491 static int log_extended(
1492         struct ldb_module *module,
1493         struct ldb_request *req)
1494 {
1495         struct audit_callback_context *context = NULL;
1496         struct ldb_request *new_req = NULL;
1497         struct ldb_context *ldb = NULL;
1498         int ret;
1499
1500         /*
1501          * Currently we only log replication extended operations
1502          */
1503         if (strcmp(
1504                 req->op.extended.oid,
1505                 DSDB_EXTENDED_REPLICATED_OBJECTS_OID) != 0) {
1506
1507                 return ldb_next_request(module, req);
1508         }
1509         ldb = ldb_module_get_ctx(module);
1510         context = talloc_zero(req, struct audit_callback_context);
1511
1512         if (context == NULL) {
1513                 return ldb_oom(ldb);
1514         }
1515         context->request = req;
1516         context->module  = module;
1517         /*
1518          * We want to log the return code status, so we need to register
1519          * a callback function to get the actual result.
1520          * We need to take a new copy so that we don't alter the callers copy
1521          */
1522         ret = ldb_build_extended_req(
1523                 &new_req,
1524                 ldb,
1525                 req,
1526                 req->op.extended.oid,
1527                 req->op.extended.data,
1528                 req->controls,
1529                 context,
1530                 audit_callback,
1531                 req);
1532         if (ret != LDB_SUCCESS) {
1533                 return ret;
1534         }
1535         ret = add_transaction_id(module, new_req);
1536         if (ret != LDB_SUCCESS) {
1537                 return ret;
1538         }
1539         return ldb_next_request(module, new_req);
1540 }
1541
1542 /*
1543  * @brief module initialisation
1544  */
1545 static int log_init(struct ldb_module *module)
1546 {
1547
1548         struct ldb_context *ldb = ldb_module_get_ctx(module);
1549         struct audit_context *context = NULL;
1550         struct loadparm_context *lp_ctx
1551                 = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
1552                                         struct loadparm_context);
1553         struct tevent_context *ev = ldb_get_event_context(ldb);
1554         bool sdb_events = false;
1555         bool pwd_events = false;
1556
1557         context = talloc_zero(module, struct audit_context);
1558         if (context == NULL) {
1559                 return ldb_module_oom(module);
1560         }
1561
1562         if (lp_ctx != NULL) {
1563                 sdb_events = lpcfg_dsdb_event_notification(lp_ctx);
1564                 pwd_events = lpcfg_dsdb_password_event_notification(lp_ctx);
1565         }
1566         if (sdb_events || pwd_events) {
1567                 context->send_samdb_events = sdb_events;
1568                 context->send_password_events = pwd_events;
1569                 context->msg_ctx = imessaging_client_init(context,
1570                                                           lp_ctx,
1571                                                           ev);
1572         }
1573
1574         ldb_module_set_private(module, context);
1575         return ldb_next_init(module);
1576 }
1577
1578 static const struct ldb_module_ops ldb_audit_log_module_ops = {
1579         .name              = "audit_log",
1580         .init_context      = log_init,
1581         .add               = log_add,
1582         .modify            = log_modify,
1583         .del               = log_delete,
1584         .start_transaction = log_start_transaction,
1585         .prepare_commit    = log_prepare_commit,
1586         .end_transaction   = log_end_transaction,
1587         .del_transaction   = log_del_transaction,
1588         .extended          = log_extended,
1589 };
1590
1591 int ldb_audit_log_module_init(const char *version)
1592 {
1593         LDB_MODULE_CHECK_VERSION(version);
1594         return ldb_register_module(&ldb_audit_log_module_ops);
1595 }