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/>.
27 #include "librpc/ndr/libndr.h"
28 #include "lib/tsocket/tsocket.h"
29 #include "libcli/security/dom_sid.h"
30 #include "lib/messaging/messaging.h"
31 #include "auth/common_auth.h"
32 #include "audit_logging.h"
35 * @brief Get a human readable timestamp.
37 * Returns the current time formatted as
38 * "Tue, 14 Mar 2017 08:38:42.209028 NZDT"
40 * The returned string is allocated by talloc in the supplied context.
41 * It is the callers responsibility to free it.
43 * @param mem_ctx talloc memory context that owns the returned string.
45 * @return a human readable time stamp, or NULL in the event of an error.
48 char* audit_get_timestamp(TALLOC_CTX
*frame
)
50 char buffer
[40]; /* formatted time less usec and timezone */
51 char tz
[10]; /* formatted time zone */
52 struct tm
* tm_info
; /* current local time */
53 struct timeval tv
; /* current system time */
54 int ret
; /* response code */
55 char * ts
; /* formatted time stamp */
57 ret
= gettimeofday(&tv
, NULL
);
59 DBG_ERR("Unable to get time of day: (%d) %s\n",
65 tm_info
= localtime(&tv
.tv_sec
);
66 if (tm_info
== NULL
) {
67 DBG_ERR("Unable to determine local time\n");
71 strftime(buffer
, sizeof(buffer
)-1, "%a, %d %b %Y %H:%M:%S", tm_info
);
72 strftime(tz
, sizeof(tz
)-1, "%Z", tm_info
);
73 ts
= talloc_asprintf(frame
, "%s.%06ld %s", buffer
, tv
.tv_usec
, tz
);
75 DBG_ERR("Out of memory formatting time stamp\n");
81 * @brief write an audit message to the audit logs.
83 * Write a human readable text audit message to the samba logs.
85 * @param prefix Text to be printed at the start of the log line
86 * @param message The content of the log line.
87 * @param debub_class The debug class to log the message with.
88 * @param debug_level The debug level to log the message with.
90 void audit_log_human_text(const char* prefix
,
95 DEBUGC(debug_class
, debug_level
, ("%s %s\n", prefix
, message
));
100 * Constant for empty json object initialisation
102 const struct json_object json_empty_object
= {.valid
= false, .root
= NULL
};
104 * @brief write a json object to the samba audit logs.
106 * Write the json object to the audit logs as a formatted string
108 * @param message The content of the log line.
109 * @param debub_class The debug class to log the message with.
110 * @param debug_level The debug level to log the message with.
112 void audit_log_json(struct json_object
* message
,
116 TALLOC_CTX
*frame
= NULL
;
119 if (json_is_invalid(message
)) {
120 DBG_ERR("Invalid JSON object, unable to log\n");
124 frame
= talloc_stackframe();
125 s
= json_to_string(frame
, message
);
127 DBG_ERR("json_to_string returned NULL, "
128 "JSON audit message could not written\n");
133 * This is very strange, but we call this routine to get a log
134 * output without the header. JSON logs all have timestamps
135 * so this only makes parsing harder.
137 * We push out the raw JSON blob without a prefix, consumers
138 * can find such lines by the leading {
140 DEBUGADDC(debug_class
, debug_level
, ("%s\n", s
));
145 * @brief get a connection to the messaging event server.
147 * Get a connection to the messaging event server registered by server_name.
149 * @param msg_ctx a valid imessaging_context.
150 * @param server_name name of messaging event server to connect to.
151 * @param server_id The event server details to populate
155 static NTSTATUS
get_event_server(
156 struct imessaging_context
*msg_ctx
,
157 const char *server_name
,
158 struct server_id
*event_server
)
161 TALLOC_CTX
*frame
= talloc_stackframe();
162 unsigned num_servers
, i
;
163 struct server_id
*servers
;
165 status
= irpc_servers_byname(
172 if (!NT_STATUS_IS_OK(status
)) {
174 "Failed to find '%s' registered on the message bus to "
175 "send JSON audit events to: %s\n",
183 * Select the first server that is listening, because we get
184 * connection refused as NT_STATUS_OBJECT_NAME_NOT_FOUND
187 for (i
= 0; i
< num_servers
; i
++) {
188 status
= imessaging_send(
193 if (NT_STATUS_IS_OK(status
)) {
194 *event_server
= servers
[i
];
200 "Failed to find '%s' registered on the message bus to "
201 "send JSON audit events to: %s\n",
205 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
209 * @brief send an audit message to a messaging event server.
211 * Send the message to a registered and listening event server.
212 * Note: Any errors are logged, and the message is not sent. This is to ensure
213 * that a poorly behaved event server does not impact Samba.
215 * As it is possible to lose messages, especially during server
216 * shut down, currently this function is primarily intended for use
217 * in integration tests.
219 * @param msg_ctx an imessaging_context, can be NULL in which case no message
221 * @param server_name the naname of the event server to send the message to.
222 * @param messag_type A message type defined in librpc/idl/messaging.idl
223 * @param message The message to send.
226 void audit_message_send(
227 struct imessaging_context
*msg_ctx
,
228 const char *server_name
,
229 uint32_t message_type
,
230 struct json_object
*message
)
232 struct server_id event_server
= {};
235 const char *message_string
= NULL
;
236 DATA_BLOB message_blob
= data_blob_null
;
237 TALLOC_CTX
*ctx
= NULL
;
239 if (json_is_invalid(message
)) {
240 DBG_ERR("Invalid JSON object, unable to send\n");
243 if (msg_ctx
== NULL
) {
244 DBG_DEBUG("No messaging context\n");
248 ctx
= talloc_new(NULL
);
250 DBG_ERR("Out of memory creating temporary context\n");
254 /* Need to refetch the address each time as the destination server may
255 * have disconnected and reconnected in the interim, in which case
256 * messages may get lost
258 status
= get_event_server(msg_ctx
, server_name
, &event_server
);
259 if (!NT_STATUS_IS_OK(status
)) {
264 message_string
= json_to_string(ctx
, message
);
265 message_blob
= data_blob_string_const(message_string
);
266 status
= imessaging_send(
273 * If the server crashed, try to find it again
275 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
276 status
= get_event_server(msg_ctx
, server_name
, &event_server
);
277 if (!NT_STATUS_IS_OK(status
)) {
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, valid will be set to false if the object
300 * could not be created.
303 struct json_object
json_new_object(void) {
305 struct json_object object
= json_empty_object
;
307 object
.root
= json_object();
308 if (object
.root
== NULL
) {
309 object
.valid
= false;
310 DBG_ERR("Unable to create JSON object\n");
318 * @brief Create a new struct json_object wrapping a JSON Array.
320 * Create a new json object, the json_object wraps the underlying json
321 * implementations JSON Array representation.
323 * Free with a call to json_free_object, note that the jansson inplementation
324 * allocates memory with malloc and not talloc.
326 * @return a struct json_object, error will be set to true if the array
327 * could not be created.
330 struct json_object
json_new_array(void) {
332 struct json_object array
= json_empty_object
;
334 array
.root
= json_array();
335 if (array
.root
== NULL
) {
337 DBG_ERR("Unable to create JSON array\n");
346 * @brief free and invalidate a previously created JSON object.
348 * Release any resources owned by a json_object, and then mark the structure
349 * as invalid. It is safe to call this multiple times on an object.
352 void json_free(struct json_object
*object
)
354 if (object
->root
!= NULL
) {
355 json_decref(object
->root
);
358 object
->valid
= false;
362 * @brief is the current JSON object invalid?
364 * Check the state of the object to determine if it is invalid.
366 * @return is the object valid?
369 bool json_is_invalid(const struct json_object
*object
)
371 return !object
->valid
;
375 * @brief Add an integer value to a JSON object.
377 * Add an integer value named 'name' to the json object.
379 * @param object the JSON object to be updated.
380 * @param name the name of the value.
381 * @param value the value.
383 * @return 0 the operation was successful
384 * -1 the operation failed
387 int json_add_int(struct json_object
*object
, const char *name
, const int value
)
390 json_t
*integer
= NULL
;
392 if (json_is_invalid(object
)) {
393 DBG_ERR("Unable to add int [%s] value [%d], "
394 "target object is invalid\n",
400 integer
= json_integer(value
);
401 if (integer
== NULL
) {
402 DBG_ERR("Unable to create integer value [%s] value [%d]\n",
408 ret
= json_object_set_new(object
->root
, name
, integer
);
410 json_decref(integer
);
411 DBG_ERR("Unable to add int [%s] value [%d]\n", name
, value
);
417 * @brief Add a boolean value to a JSON object.
419 * Add a boolean value named 'name' to the json object.
421 * @param object the JSON object to be updated.
422 * @param name the name.
423 * @param value the value.
425 * @return 0 the operation was successful
426 * -1 the operation failed
429 int json_add_bool(struct json_object
*object
,
435 if (json_is_invalid(object
)) {
436 DBG_ERR("Unable to add boolean [%s] value [%d], "
437 "target object is invalid\n",
443 ret
= json_object_set_new(object
->root
, name
, json_boolean(value
));
445 DBG_ERR("Unable to add boolean [%s] value [%d]\n", name
, value
);
451 * @brief Add a string value to a JSON object.
453 * Add a string value named 'name' to the json object.
455 * @param object the JSON object to be updated.
456 * @param name the name.
457 * @param value the value.
459 * @return 0 the operation was successful
460 * -1 the operation failed
463 int json_add_string(struct json_object
*object
,
469 if (json_is_invalid(object
)) {
470 DBG_ERR("Unable to add string [%s], target object is invalid\n",
475 json_t
*string
= json_string(value
);
476 if (string
== NULL
) {
477 DBG_ERR("Unable to add string [%s], "
478 "could not create string object\n",
482 ret
= json_object_set_new(object
->root
, name
, string
);
485 DBG_ERR("Unable to add string [%s]\n", name
);
489 ret
= json_object_set_new(object
->root
, name
, json_null());
491 DBG_ERR("Unable to add null string [%s]\n", name
);
499 * @brief Assert that the current JSON object is an array.
501 * Check that the current object is a JSON array, and if not
502 * invalidate the object. We also log an error message as this indicates
503 * bug in the calling code.
505 * @param object the JSON object to be validated.
507 void json_assert_is_array(struct json_object
*array
) {
509 if (json_is_invalid(array
)) {
513 if (json_is_array(array
->root
) == false) {
514 DBG_ERR("JSON object is not an array\n");
515 array
->valid
= false;
521 * @brief Add a JSON object to a JSON object.
523 * Add a JSON object named 'name' to the json object.
525 * @param object the JSON object to be updated.
526 * @param name the name.
527 * @param value the value.
529 * @return 0 the operation was successful
530 * -1 the operation failed
533 int json_add_object(struct json_object
*object
,
535 struct json_object
*value
)
540 if (value
!= NULL
&& json_is_invalid(value
)) {
541 DBG_ERR("Invalid JSON object [%s] supplied\n", name
);
544 if (json_is_invalid(object
)) {
545 DBG_ERR("Unable to add object [%s], target object is invalid\n",
550 jv
= value
== NULL
? json_null() : value
->root
;
552 if (json_is_array(object
->root
)) {
553 ret
= json_array_append_new(object
->root
, jv
);
554 } else if (json_is_object(object
->root
)) {
555 ret
= json_object_set_new(object
->root
, name
, jv
);
557 DBG_ERR("Invalid JSON object type\n");
561 DBG_ERR("Unable to add object [%s]\n", name
);
567 * @brief Add a string to a JSON object, truncating if necessary.
570 * Add a string value named 'name' to the json object, the string will be
571 * truncated if it is more than len characters long. If len is 0 the value
572 * is encoded as a JSON null.
575 * @param object the JSON object to be updated.
576 * @param name the name.
577 * @param value the value.
578 * @param len the maximum number of characters to be copied.
580 * @return 0 the operation was successful
581 * -1 the operation failed
584 int json_add_stringn(struct json_object
*object
,
591 if (json_is_invalid(object
)) {
592 DBG_ERR("Unable to add string [%s], target object is invalid\n",
597 if (value
!= NULL
&& len
> 0) {
598 json_t
*string
= NULL
;
601 strncpy(buffer
, value
, len
);
604 string
= json_string(buffer
);
605 if (string
== NULL
) {
606 DBG_ERR("Unable to add string [%s], "
607 "could not create string object\n",
611 ret
= json_object_set_new(object
->root
, name
, string
);
614 DBG_ERR("Unable to add string [%s]\n", name
);
618 ret
= json_object_set_new(object
->root
, name
, json_null());
620 DBG_ERR("Unable to add null string [%s]\n", name
);
628 * @brief Add a version object to a JSON object
630 * Add a version object to the JSON object
631 * "version":{"major":1, "minor":0}
633 * The version tag is intended to aid the processing of the JSON messages
634 * The major version number should change when an attribute is:
637 * - its meaning changes
638 * - its contents change format
639 * The minor version should change whenever a new attribute is added and for
640 * minor bug fixes to an attributes content.
643 * @param object the JSON object to be updated.
644 * @param major the major version number
645 * @param minor the minor version number
647 * @return 0 the operation was successful
648 * -1 the operation failed
650 int json_add_version(struct json_object
*object
, int major
, int minor
)
653 struct json_object version
;
655 if (json_is_invalid(object
)) {
656 DBG_ERR("Unable to add version, target object is invalid\n");
660 version
= json_new_object();
661 if (json_is_invalid(&version
)) {
662 DBG_ERR("Unable to add version, failed to create object\n");
665 ret
= json_add_int(&version
, "major", major
);
670 ret
= json_add_int(&version
, "minor", minor
);
675 ret
= json_add_object(object
, "version", &version
);
684 * @brief add an ISO 8601 timestamp to the object.
686 * Add the current date and time as a timestamp in ISO 8601 format
689 * "timestamp":"2017-03-06T17:18:04.455081+1300"
692 * @param object the JSON object to be updated.
694 * @return 0 the operation was successful
695 * -1 the operation failed
697 int json_add_timestamp(struct json_object
*object
)
699 char buffer
[40]; /* formatted time less usec and timezone */
700 char timestamp
[65]; /* the formatted ISO 8601 time stamp */
701 char tz
[10]; /* formatted time zone */
702 struct tm
* tm_info
; /* current local time */
703 struct timeval tv
; /* current system time */
704 int r
; /* response code from gettimeofday */
705 int ret
; /* return code from json operations */
707 if (json_is_invalid(object
)) {
708 DBG_ERR("Unable to add time stamp, target object is invalid\n");
712 r
= gettimeofday(&tv
, NULL
);
714 DBG_ERR("Unable to get time of day: (%d) %s\n",
720 tm_info
= localtime(&tv
.tv_sec
);
721 if (tm_info
== NULL
) {
722 DBG_ERR("Unable to determine local time\n");
726 strftime(buffer
, sizeof(buffer
)-1, "%Y-%m-%dT%T", tm_info
);
727 strftime(tz
, sizeof(tz
)-1, "%z", tm_info
);
735 ret
= json_add_string(object
, "timestamp", timestamp
);
737 DBG_ERR("Unable to add time stamp to JSON object\n");
743 *@brief Add a tsocket_address to a JSON object
745 * Add the string representation of a Samba tsocket_address to the object.
747 * "localAddress":"ipv6::::0"
750 * @param object the JSON object to be updated.
751 * @param name the name.
752 * @param address the tsocket_address.
754 * @return 0 the operation was successful
755 * -1 the operation failed
758 int json_add_address(struct json_object
*object
,
760 const struct tsocket_address
*address
)
764 if (json_is_invalid(object
)) {
765 DBG_ERR("Unable to add address [%s], "
766 "target object is invalid\n",
771 if (address
== NULL
) {
772 ret
= json_object_set_new(object
->root
, name
, json_null());
774 DBG_ERR("Unable to add null address [%s]\n", name
);
778 TALLOC_CTX
*ctx
= talloc_new(NULL
);
782 DBG_ERR("Out of memory adding address [%s]\n", name
);
786 s
= tsocket_address_string(address
, ctx
);
788 DBG_ERR("Out of memory adding address [%s]\n", name
);
792 ret
= json_add_string(object
, name
, s
);
795 "Unable to add address [%s] value [%s]\n", name
, s
);
805 * @brief Add a formatted string representation of a sid to a json object.
807 * Add the string representation of a Samba sid to the object.
812 * @param object the JSON object to be updated.
813 * @param name the name.
816 * @return 0 the operation was successful
817 * -1 the operation failed
820 int json_add_sid(struct json_object
*object
,
822 const struct dom_sid
*sid
)
826 if (json_is_invalid(object
)) {
827 DBG_ERR("Unable to add SID [%s], "
828 "target object is invalid\n",
834 ret
= json_object_set_new(object
->root
, name
, json_null());
836 DBG_ERR("Unable to add null SID [%s]\n", name
);
840 struct dom_sid_buf sid_buf
;
842 ret
= json_add_string(
843 object
, name
, dom_sid_str_buf(sid
, &sid_buf
));
845 DBG_ERR("Unable to add SID [%s] value [%s]\n",
855 * @brief Add a formatted string representation of a guid to a json object.
857 * Add the string representation of a Samba GUID to the object.
859 * "guid":"1fb9f2ee-2a4d-4bf8-af8b-cb9d4529a9ab"
862 * @param object the JSON object to be updated.
863 * @param name the name.
864 * @param guid the guid.
866 * @return 0 the operation was successful
867 * -1 the operation failed
871 int json_add_guid(struct json_object
*object
,
873 const struct GUID
*guid
)
878 if (json_is_invalid(object
)) {
879 DBG_ERR("Unable to add GUID [%s], "
880 "target object is invalid\n",
886 ret
= json_object_set_new(object
->root
, name
, json_null());
888 DBG_ERR("Unable to add null GUID [%s]\n", name
);
893 struct GUID_txt_buf guid_buff
;
895 guid_str
= GUID_buf_string(guid
, &guid_buff
);
896 ret
= json_add_string(object
, name
, guid_str
);
898 DBG_ERR("Unable to guid GUID [%s] value [%s]\n",
908 * @brief Convert a JSON object into a string
910 * Convert the jsom object into a string suitable for printing on a log line,
911 * i.e. with no embedded line breaks.
913 * If the object is invalid it logs an error and returns NULL.
915 * @param mem_ctx the talloc memory context owning the returned string
916 * @param object the json object.
918 * @return A string representation of the object or NULL if the object
921 char *json_to_string(TALLOC_CTX
*mem_ctx
, const struct json_object
*object
)
924 char *json_string
= NULL
;
926 if (json_is_invalid(object
)) {
927 DBG_ERR("Invalid JSON object, unable to convert to string\n");
931 if (object
->root
== NULL
) {
936 * json_dumps uses malloc, so need to call free(json) to release
939 json
= json_dumps(object
->root
, 0);
941 DBG_ERR("Unable to convert JSON object to string\n");
945 json_string
= talloc_strdup(mem_ctx
, json
);
946 if (json_string
== NULL
) {
948 DBG_ERR("Unable to copy JSON object string to talloc string\n");
957 * @brief get a json array named "name" from the json object.
959 * Get the array attribute named name, creating it if it does not exist.
961 * @param object the json object.
962 * @param name the name of the array attribute
964 * @return The array object, will be created if it did not exist.
966 struct json_object
json_get_array(struct json_object
*object
, const char *name
)
969 struct json_object array
= json_empty_object
;
973 if (json_is_invalid(object
)) {
974 DBG_ERR("Invalid JSON object, unable to get array [%s]\n",
980 array
= json_new_array();
981 if (json_is_invalid(&array
)) {
982 DBG_ERR("Unable to create new array for [%s]\n", name
);
986 a
= json_object_get(object
->root
, name
);
991 ret
= json_array_extend(array
.root
, a
);
993 DBG_ERR("Unable to get array [%s]\n", name
);
1002 * @brief get a json object named "name" from the json object.
1004 * Get the object attribute named name, creating it if it does not exist.
1006 * @param object the json object.
1007 * @param name the name of the object attribute
1009 * @return The object, will be created if it did not exist.
1011 struct json_object
json_get_object(struct json_object
*object
, const char *name
)
1014 struct json_object o
= json_new_object();
1018 if (json_is_invalid(object
)) {
1019 DBG_ERR("Invalid JSON object, unable to get object [%s]\n",
1025 v
= json_object_get(object
->root
, name
);
1029 ret
= json_object_update(o
.root
, v
);
1031 DBG_ERR("Unable to get object [%s]\n", name
);