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