talloc_stack: Call talloc destructors while frame is still around
[Samba.git] / lib / audit_logging / audit_logging.c
blob13ff3453dcca1aa9879f5043f376fbe51b520db0
1 /*
2 common routines for audit logging
4 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
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.
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.
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/>.
21 * Error handling:
23 * The json_object structure contains a boolean 'error'. This is set whenever
24 * an error is detected. All the library functions check this flag and return
25 * immediately if it is set.
27 * if (object->error) {
28 * return;
29 * }
31 * This allows the operations to be sequenced naturally with out the clutter
32 * of error status checks.
34 * audit = json_new_object();
35 * json_add_version(&audit, OPERATION_MAJOR, OPERATION_MINOR);
36 * json_add_int(&audit, "statusCode", ret);
37 * json_add_string(&audit, "status", ldb_strerror(ret));
38 * json_add_string(&audit, "operation", operation);
39 * json_add_address(&audit, "remoteAddress", remote);
40 * json_add_sid(&audit, "userSid", sid);
41 * json_add_string(&audit, "dn", dn);
42 * json_add_guid(&audit, "transactionId", &ac->transaction_guid);
43 * json_add_guid(&audit, "sessionId", unique_session_token);
45 * The assumptions are that errors will be rare, and that the audit logging
46 * code should not cause failures. So errors are logged but processing
47 * continues on a best effort basis.
50 #include "includes.h"
52 #include "librpc/ndr/libndr.h"
53 #include "lib/tsocket/tsocket.h"
54 #include "libcli/security/dom_sid.h"
55 #include "lib/messaging/messaging.h"
56 #include "auth/common_auth.h"
57 #include "audit_logging.h"
60 * @brief Get a human readable timestamp.
62 * Returns the current time formatted as
63 * "Tue, 14 Mar 2017 08:38:42.209028 NZDT"
65 * The returned string is allocated by talloc in the supplied context.
66 * It is the callers responsibility to free it.
68 * @param mem_ctx talloc memory context that owns the returned string.
70 * @return a human readable time stamp.
73 char* audit_get_timestamp(TALLOC_CTX *frame)
75 char buffer[40]; /* formatted time less usec and timezone */
76 char tz[10]; /* formatted time zone */
77 struct tm* tm_info; /* current local time */
78 struct timeval tv; /* current system time */
79 int r; /* response code from gettimeofday */
80 char * ts; /* formatted time stamp */
82 r = gettimeofday(&tv, NULL);
83 if (r) {
84 DBG_ERR("Unable to get time of day: (%d) %s\n",
85 errno,
86 strerror(errno));
87 return NULL;
90 tm_info = localtime(&tv.tv_sec);
91 if (tm_info == NULL) {
92 DBG_ERR("Unable to determine local time\n");
93 return NULL;
96 strftime(buffer, sizeof(buffer)-1, "%a, %d %b %Y %H:%M:%S", tm_info);
97 strftime(tz, sizeof(tz)-1, "%Z", tm_info);
98 ts = talloc_asprintf(frame, "%s.%06ld %s", buffer, tv.tv_usec, tz);
99 if (ts == NULL) {
100 DBG_ERR("Out of memory formatting time stamp\n");
102 return ts;
106 * @brief write an audit message to the audit logs.
108 * Write a human readable text audit message to the samba logs.
110 * @param prefix Text to be printed at the start of the log line
111 * @param message The content of the log line.
112 * @param debub_class The debug class to log the message with.
113 * @param debug_level The debug level to log the message with.
115 void audit_log_human_text(const char* prefix,
116 const char* message,
117 int debug_class,
118 int debug_level)
120 DEBUGC(debug_class, debug_level, ("%s %s\n", prefix, message));
123 #ifdef HAVE_JANSSON
125 * @brief write a json object to the samba audit logs.
127 * Write the json object to the audit logs as a formatted string
129 * @param prefix Text to be printed at the start of the log line
130 * @param message The content of the log line.
131 * @param debub_class The debug class to log the message with.
132 * @param debug_level The debug level to log the message with.
134 void audit_log_json(const char* prefix,
135 struct json_object* message,
136 int debug_class,
137 int debug_level)
139 TALLOC_CTX *ctx = talloc_new(NULL);
140 char *s = json_to_string(ctx, message);
141 DEBUGC(debug_class, debug_level, ("JSON %s: %s\n", prefix, s));
142 TALLOC_FREE(ctx);
146 * @brief get a connection to the messaging event server.
148 * Get a connection to the messaging event server registered by server_name.
150 * @param msg_ctx a valid imessaging_context.
151 * @param server_name name of messaging event server to connect to.
152 * @param server_id The event server details to populate
154 * @return NTSTATUS
156 static NTSTATUS get_event_server(
157 struct imessaging_context *msg_ctx,
158 const char *server_name,
159 struct server_id *event_server)
161 NTSTATUS status;
162 TALLOC_CTX *frame = talloc_stackframe();
163 unsigned num_servers, i;
164 struct server_id *servers;
166 status = irpc_servers_byname(
167 msg_ctx,
168 frame,
169 server_name,
170 &num_servers,
171 &servers);
173 if (!NT_STATUS_IS_OK(status)) {
174 DBG_NOTICE(
175 "Failed to find '%s' registered on the message bus to "
176 "send audit events to: %s\n",
177 server_name,
178 nt_errstr(status));
179 TALLOC_FREE(frame);
180 return status;
184 * Select the first server that is listening, because we get
185 * connection refused as NT_STATUS_OBJECT_NAME_NOT_FOUND
186 * without waiting
188 for (i = 0; i < num_servers; i++) {
189 status = imessaging_send(
190 msg_ctx,
191 servers[i],
192 MSG_PING,
193 &data_blob_null);
194 if (NT_STATUS_IS_OK(status)) {
195 *event_server = servers[i];
196 TALLOC_FREE(frame);
197 return NT_STATUS_OK;
200 DBG_NOTICE(
201 "Failed to find '%s' registered on the message bus to "
202 "send audit events to: %s\n",
203 server_name,
204 nt_errstr(status));
205 TALLOC_FREE(frame);
206 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
210 * @brief send an audit message to a messaging event server.
212 * Send the message to a registered and listening event server.
213 * Note: Any errors are logged, and the message is not sent. This is to ensure
214 * that a poorly behaved event server does not impact Samba.
216 * As it is possible to lose messages, especially during server
217 * shut down, currently this function is primarily intended for use
218 * in integration tests.
220 * @param msg_ctx an imessaging_context, can be NULL in which case no message
221 * will be sent.
222 * @param server_name the naname of the event server to send the message to.
223 * @param messag_type A message type defined in librpc/idl/messaging.idl
224 * @param message The message to send.
227 void audit_message_send(
228 struct imessaging_context *msg_ctx,
229 const char *server_name,
230 uint32_t message_type,
231 struct json_object *message)
233 struct server_id event_server;
234 NTSTATUS status;
236 const char *message_string = NULL;
237 DATA_BLOB message_blob = data_blob_null;
238 TALLOC_CTX *ctx = talloc_new(NULL);
240 if (msg_ctx == NULL) {
241 DBG_DEBUG("No messaging context\n");
242 TALLOC_FREE(ctx);
243 return;
246 /* Need to refetch the address each time as the destination server may
247 * have disconnected and reconnected in the interim, in which case
248 * messages may get lost
250 status = get_event_server(msg_ctx, server_name, &event_server);
251 if (!NT_STATUS_IS_OK(status) &&
252 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
253 DBG_ERR("get_event_server for %s returned (%s)\n",
254 server_name,
255 nt_errstr(status));
256 TALLOC_FREE(ctx);
257 return;
260 message_string = json_to_string(ctx, message);
261 message_blob = data_blob_string_const(message_string);
262 status = imessaging_send(
263 msg_ctx,
264 event_server,
265 message_type,
266 &message_blob);
269 * If the server crashed, try to find it again
271 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
272 status = get_event_server(msg_ctx, server_name, &event_server);
273 if (!NT_STATUS_IS_OK(status) &&
274 !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
275 DBG_ERR("get_event_server for %s returned (%s)\n",
276 server_name,
277 nt_errstr(status));
278 TALLOC_FREE(ctx);
279 return;
281 imessaging_send(
282 msg_ctx,
283 event_server,
284 message_type,
285 &message_blob);
287 TALLOC_FREE(ctx);
291 * @brief Create a new struct json_object, wrapping a JSON Object.
293 * Create a new json object, the json_object wraps the underlying json
294 * implementations JSON Object representation.
296 * Free with a call to json_free_object, note that the jansson inplementation
297 * allocates memory with malloc and not talloc.
299 * @return a struct json_object, error will be set to true if the object
300 * could not be created.
303 struct json_object json_new_object(void) {
305 struct json_object object;
306 object.error = false;
308 object.root = json_object();
309 if (object.root == NULL) {
310 object.error = true;
311 DBG_ERR("Unable to create json_object\n");
313 return object;
317 * @brief Create a new struct json_object wrapping a JSON Array.
319 * Create a new json object, the json_object wraps the underlying json
320 * implementations JSON Array representation.
322 * Free with a call to json_free_object, note that the jansson inplementation
323 * allocates memory with malloc and not talloc.
325 * @return a struct json_object, error will be set to true if the array
326 * could not be created.
329 struct json_object json_new_array(void) {
331 struct json_object array;
332 array.error = false;
334 array.root = json_array();
335 if (array.root == NULL) {
336 array.error = true;
337 DBG_ERR("Unable to create json_array\n");
339 return array;
344 * @brief free and invalidate a previously created JSON object.
346 * Release any resources owned by a json_object, and then mark the structure
347 * as invalid. It is safe to call this multiple times on an object.
350 void json_free(struct json_object *object)
352 if (object->root != NULL) {
353 json_decref(object->root);
355 object->root = NULL;
356 object->error = true;
360 * @brief is the current JSON object invalid?
362 * Check the state of the object to determine if it is invalid.
364 * @return is the object valid?
367 bool json_is_invalid(struct json_object *object)
369 return object->error;
373 * @brief Add an integer value to a JSON object.
375 * Add an integer value named 'name' to the json object.
376 * In the event of an error object will be invalidated.
378 * @param object the JSON object to be updated.
379 * @param name the name of the value.
380 * @param value the value.
383 void json_add_int(struct json_object *object,
384 const char* name,
385 const int value)
387 int rc = 0;
389 if (object->error) {
390 return;
393 rc = json_object_set_new(object->root, name, json_integer(value));
394 if (rc) {
395 DBG_ERR("Unable to set name [%s] value [%d]\n", name, value);
396 object->error = true;
401 * @brief Add a boolean value to a JSON object.
403 * Add a boolean value named 'name' to the json object.
404 * In the event of an error object will be invalidated.
406 * @param object the JSON object to be updated.
407 * @param name the name.
408 * @param value the value.
411 void json_add_bool(struct json_object *object,
412 const char* name,
413 const bool value)
415 int rc = 0;
417 if (object->error) {
418 return;
421 rc = json_object_set_new(object->root, name, json_boolean(value));
422 if (rc) {
423 DBG_ERR("Unable to set name [%s] value [%d]\n", name, value);
424 object->error = true;
430 * @brief Add a string value to a JSON object.
432 * Add a string value named 'name' to the json object.
433 * In the event of an error object will be invalidated.
435 * @param object the JSON object to be updated.
436 * @param name the name.
437 * @param value the value.
440 void json_add_string(struct json_object *object,
441 const char* name,
442 const char* value)
444 int rc = 0;
446 if (object->error) {
447 return;
450 if (value) {
451 rc = json_object_set_new(
452 object->root,
453 name,
454 json_string(value));
455 } else {
456 rc = json_object_set_new(object->root, name, json_null());
458 if (rc) {
459 DBG_ERR("Unable to set name [%s] value [%s]\n", name, value);
460 object->error = true;
465 * @brief Assert that the current JSON object is an array.
467 * Check that the current object is a JSON array, and if not
468 * invalidate the object. We also log an error message as this indicates
469 * bug in the calling code.
471 * @param object the JSON object to be validated.
473 void json_assert_is_array(struct json_object *array) {
475 if (array->error) {
476 return;
479 if (json_is_array(array->root) == false) {
480 DBG_ERR("JSON object is not an array\n");
481 array->error = true;
482 return;
487 * @brief Add a JSON object to a JSON object.
489 * Add a JSON object named 'name' to the json object.
490 * In the event of an error object will be invalidated.
492 * @param object the JSON object to be updated.
493 * @param name the name.
494 * @param value the value.
497 void json_add_object(struct json_object *object,
498 const char* name,
499 struct json_object *value)
501 int rc = 0;
502 json_t *jv = NULL;
504 if (object->error) {
505 return;
508 if (value != NULL && value->error) {
509 object->error = true;
510 return;
513 jv = value == NULL ? json_null() : value->root;
515 if (json_is_array(object->root)) {
516 rc = json_array_append_new(object->root, jv);
517 } else if (json_is_object(object->root)) {
518 rc = json_object_set_new(object->root, name, jv);
519 } else {
520 DBG_ERR("Invalid JSON object type\n");
521 object->error = true;
523 if (rc) {
524 DBG_ERR("Unable to add object [%s]\n", name);
525 object->error = true;
530 * @brief Add a string to a JSON object, truncating if necessary.
533 * Add a string value named 'name' to the json object, the string will be
534 * truncated if it is more than len characters long. If len is 0 the value
535 * is encoded as a JSON null.
537 * In the event of an error object will be invalidated.
539 * @param object the JSON object to be updated.
540 * @param name the name.
541 * @param value the value.
542 * @param len the maximum number of characters to be copied.
545 void json_add_stringn(struct json_object *object,
546 const char *name,
547 const char *value,
548 const size_t len)
551 int rc = 0;
552 if (object->error) {
553 return;
556 if (value != NULL && len > 0) {
557 char buffer[len+1];
558 strncpy(buffer, value, len);
559 buffer[len] = '\0';
560 rc = json_object_set_new(object->root,
561 name,
562 json_string(buffer));
563 } else {
564 rc = json_object_set_new(object->root, name, json_null());
566 if (rc) {
567 DBG_ERR("Unable to set name [%s] value [%s]\n", name, value);
568 object->error = true;
573 * @brief Add a version object to a JSON object
575 * Add a version object to the JSON object
576 * "version":{"major":1, "minor":0}
578 * The version tag is intended to aid the processing of the JSON messages
579 * The major version number should change when an attribute is:
580 * - renamed
581 * - removed
582 * - its meaning changes
583 * - its contents change format
584 * The minor version should change whenever a new attribute is added and for
585 * minor bug fixes to an attributes content.
587 * In the event of an error object will be invalidated.
589 * @param object the JSON object to be updated.
590 * @param major the major version number
591 * @param minor the minor version number
593 void json_add_version(struct json_object *object, int major, int minor)
595 struct json_object version = json_new_object();
596 json_add_int(&version, "major", major);
597 json_add_int(&version, "minor", minor);
598 json_add_object(object, "version", &version);
602 * @brief add an ISO 8601 timestamp to the object.
604 * Add the current date and time as a timestamp in ISO 8601 format
605 * to a JSON object
607 * "timestamp":"2017-03-06T17:18:04.455081+1300"
609 * In the event of an error object will be invalidated.
611 * @param object the JSON object to be updated.
613 void json_add_timestamp(struct json_object *object)
615 char buffer[40]; /* formatted time less usec and timezone */
616 char timestamp[65]; /* the formatted ISO 8601 time stamp */
617 char tz[10]; /* formatted time zone */
618 struct tm* tm_info; /* current local time */
619 struct timeval tv; /* current system time */
620 int r; /* response code from gettimeofday */
622 if (object->error) {
623 return;
626 r = gettimeofday(&tv, NULL);
627 if (r) {
628 DBG_ERR("Unable to get time of day: (%d) %s\n",
629 errno,
630 strerror(errno));
631 object->error = true;
632 return;
635 tm_info = localtime(&tv.tv_sec);
636 if (tm_info == NULL) {
637 DBG_ERR("Unable to determine local time\n");
638 object->error = true;
639 return;
642 strftime(buffer, sizeof(buffer)-1, "%Y-%m-%dT%T", tm_info);
643 strftime(tz, sizeof(tz)-1, "%z", tm_info);
644 snprintf(
645 timestamp,
646 sizeof(timestamp),
647 "%s.%06ld%s",
648 buffer,
649 tv.tv_usec,
650 tz);
651 json_add_string(object, "timestamp", timestamp);
656 *@brief Add a tsocket_address to a JSON object
658 * Add the string representation of a Samba tsocket_address to the object.
660 * "localAddress":"ipv6::::0"
662 * In the event of an error object will be invalidated.
664 * @param object the JSON object to be updated.
665 * @param name the name.
666 * @param address the tsocket_address.
669 void json_add_address(struct json_object *object,
670 const char *name,
671 const struct tsocket_address *address)
674 if (object->error) {
675 return;
677 if (address == NULL) {
678 int rc = json_object_set_new(object->root, name, json_null());
679 if (rc) {
680 DBG_ERR("Unable to set address [%s] to null\n", name);
681 object->error = true;
683 } else {
684 TALLOC_CTX *ctx = talloc_new(NULL);
685 char *s = NULL;
687 s = tsocket_address_string(address, ctx);
688 json_add_string(object, name, s);
689 TALLOC_FREE(ctx);
694 * @brief Add a formatted string representation of a sid to a json object.
696 * Add the string representation of a Samba sid to the object.
698 * "sid":"S-1-5-18"
700 * In the event of an error object will be invalidated.
702 * @param object the JSON object to be updated.
703 * @param name the name.
704 * @param sid the sid
707 void json_add_sid(struct json_object *object,
708 const char *name,
709 const struct dom_sid *sid)
712 if (object->error) {
713 return;
715 if (sid == NULL) {
716 int rc = json_object_set_new(object->root, name, json_null());
717 if (rc) {
718 DBG_ERR("Unable to set SID [%s] to null\n", name);
719 object->error = true;
721 } else {
722 char sid_buf[DOM_SID_STR_BUFLEN];
724 dom_sid_string_buf(sid, sid_buf, sizeof(sid_buf));
725 json_add_string(object, name, sid_buf);
730 * @brief Add a formatted string representation of a guid to a json object.
732 * Add the string representation of a Samba GUID to the object.
734 * "guid":"1fb9f2ee-2a4d-4bf8-af8b-cb9d4529a9ab"
736 * In the event of an error object will be invalidated.
738 * @param object the JSON object to be updated.
739 * @param name the name.
740 * @param guid the guid.
744 void json_add_guid(struct json_object *object,
745 const char *name,
746 const struct GUID *guid)
750 if (object->error) {
751 return;
753 if (guid == NULL) {
754 int rc = json_object_set_new(object->root, name, json_null());
755 if (rc) {
756 DBG_ERR("Unable to set GUID [%s] to null\n", name);
757 object->error = true;
759 } else {
760 char *guid_str;
761 struct GUID_txt_buf guid_buff;
763 guid_str = GUID_buf_string(guid, &guid_buff);
764 json_add_string(object, name, guid_str);
770 * @brief Convert a JSON object into a string
772 * Convert the jsom object into a string suitable for printing on a log line,
773 * i.e. with no embedded line breaks.
775 * If the object is invalid it returns NULL.
777 * @param mem_ctx the talloc memory context owning the returned string
778 * @param object the json object.
780 * @return A string representation of the object or NULL if the object
781 * is invalid.
783 char *json_to_string(TALLOC_CTX *mem_ctx,
784 struct json_object *object)
786 char *json = NULL;
787 char *json_string = NULL;
789 if (object->error) {
790 return NULL;
794 * json_dumps uses malloc, so need to call free(json) to release
795 * the memory
797 json = json_dumps(object->root, 0);
798 if (json == NULL) {
799 DBG_ERR("Unable to convert JSON object to string\n");
800 return NULL;
803 json_string = talloc_strdup(mem_ctx, json);
804 if (json_string == NULL) {
805 free(json);
806 DBG_ERR("Unable to copy JSON object string to talloc string\n");
807 return NULL;
809 free(json);
811 return json_string;
815 * @brief get a json array named "name" from the json object.
817 * Get the array attribute named name, creating it if it does not exist.
819 * @param object the json object.
820 * @param name the name of the array attribute
822 * @return The array object, will be created if it did not exist.
824 struct json_object json_get_array(struct json_object *object,
825 const char* name)
828 struct json_object array = json_new_array();
829 json_t *a = NULL;
831 if (object->error) {
832 array.error = true;
833 return array;
836 a = json_object_get(object->root, name);
837 if (a == NULL) {
838 return array;
840 json_array_extend(array.root, a);
842 return array;
846 * @brief get a json object named "name" from the json object.
848 * Get the object attribute named name, creating it if it does not exist.
850 * @param object the json object.
851 * @param name the name of the object attribute
853 * @return The object, will be created if it did not exist.
855 struct json_object json_get_object(struct json_object *object,
856 const char* name)
859 struct json_object o = json_new_object();
860 json_t *v = NULL;
862 if (object->error) {
863 o.error = true;
864 return o;
867 v = json_object_get(object->root, name);
868 if (v == NULL) {
869 return o;
871 json_object_update(o.root, v);
873 return o;
875 #endif