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 "libcli/security/security_token.h"
31 #include "lib/messaging/messaging.h"
32 #include "auth/common_auth.h"
33 #include "audit_logging.h"
34 #include "auth/authn_policy.h"
37 * @brief Get a human readable timestamp.
39 * Returns the current time formatted as
40 * "Tue, 14 Mar 2017 08:38:42.209028 NZDT"
42 * The returned string is allocated by talloc in the supplied context.
43 * It is the callers responsibility to free it.
45 * @param mem_ctx talloc memory context that owns the returned string.
47 * @return a human readable time stamp, or NULL in the event of an error.
50 char* audit_get_timestamp(TALLOC_CTX
*frame
)
52 char buffer
[40]; /* formatted time less usec and timezone */
53 char tz
[10]; /* formatted time zone */
54 struct tm
* tm_info
; /* current local time */
55 struct timeval tv
; /* current system time */
56 int ret
; /* response code */
57 char * ts
; /* formatted time stamp */
59 ret
= gettimeofday(&tv
, NULL
);
61 DBG_ERR("Unable to get time of day: (%d) %s\n",
67 tm_info
= localtime(&tv
.tv_sec
);
68 if (tm_info
== NULL
) {
69 DBG_ERR("Unable to determine local time\n");
73 strftime(buffer
, sizeof(buffer
)-1, "%a, %d %b %Y %H:%M:%S", tm_info
);
74 strftime(tz
, sizeof(tz
)-1, "%Z", tm_info
);
75 ts
= talloc_asprintf(frame
, "%s.%06ld %s", buffer
, (long)tv
.tv_usec
, tz
);
77 DBG_ERR("Out of memory formatting time stamp\n");
83 * @brief write an audit message to the audit logs.
85 * Write a human readable text audit message to the samba logs.
87 * @param prefix Text to be printed at the start of the log line
88 * @param message The content of the log line.
89 * @param debub_class The debug class to log the message with.
90 * @param debug_level The debug level to log the message with.
92 void audit_log_human_text(const char* prefix
,
97 DEBUGC(debug_class
, debug_level
, ("%s %s\n", prefix
, message
));
102 * Constant for empty json object initialisation
104 const struct json_object json_empty_object
= {.valid
= false, .root
= NULL
};
106 * @brief write a json object to the samba audit logs.
108 * Write the json object to the audit logs as a formatted string
110 * @param message The content of the log line.
111 * @param debub_class The debug class to log the message with.
112 * @param debug_level The debug level to log the message with.
114 void audit_log_json(struct json_object
* message
,
118 TALLOC_CTX
*frame
= NULL
;
121 if (json_is_invalid(message
)) {
122 DBG_ERR("Invalid JSON object, unable to log\n");
126 frame
= talloc_stackframe();
127 s
= json_to_string(frame
, message
);
129 DBG_ERR("json_to_string returned NULL, "
130 "JSON audit message could not written\n");
135 * This is very strange, but we call this routine to get a log
136 * output without the header. JSON logs all have timestamps
137 * so this only makes parsing harder.
139 * We push out the raw JSON blob without a prefix, consumers
140 * can find such lines by the leading {
142 DEBUGADDC(debug_class
, debug_level
, ("%s\n", s
));
147 * @brief get a connection to the messaging event server.
149 * Get a connection to the messaging event server registered by server_name.
151 * @param msg_ctx a valid imessaging_context.
152 * @param server_name name of messaging event server to connect to.
153 * @param server_id The event server details to populate
157 static NTSTATUS
get_event_server(
158 struct imessaging_context
*msg_ctx
,
159 const char *server_name
,
160 struct server_id
*event_server
)
163 TALLOC_CTX
*frame
= talloc_stackframe();
164 unsigned num_servers
, i
;
165 struct server_id
*servers
;
167 status
= irpc_servers_byname(
174 if (!NT_STATUS_IS_OK(status
)) {
175 DBG_DEBUG("Failed to find the target '%s' on the message bus "
176 "to send JSON audit events to: %s\n",
184 * Select the first server that is listening, because we get
185 * connection refused as NT_STATUS_OBJECT_NAME_NOT_FOUND
188 for (i
= 0; i
< num_servers
; i
++) {
189 status
= imessaging_send(
194 if (NT_STATUS_IS_OK(status
)) {
195 *event_server
= servers
[i
];
201 "Failed to find '%s' registered on the message bus to "
202 "send JSON audit events to: %s\n",
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
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
= {
238 const char *message_string
= NULL
;
239 DATA_BLOB message_blob
= data_blob_null
;
240 TALLOC_CTX
*ctx
= NULL
;
242 if (json_is_invalid(message
)) {
243 DBG_ERR("Invalid JSON object, unable to send\n");
246 if (msg_ctx
== NULL
) {
247 DBG_DEBUG("No messaging context\n");
251 ctx
= talloc_new(NULL
);
253 DBG_ERR("Out of memory creating temporary context\n");
257 /* Need to refetch the address each time as the destination server may
258 * have disconnected and reconnected in the interim, in which case
259 * messages may get lost
261 status
= get_event_server(msg_ctx
, server_name
, &event_server
);
262 if (!NT_STATUS_IS_OK(status
)) {
267 message_string
= json_to_string(ctx
, message
);
268 message_blob
= data_blob_string_const(message_string
);
269 status
= imessaging_send(
276 * If the server crashed, try to find it again
278 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
279 status
= get_event_server(msg_ctx
, server_name
, &event_server
);
280 if (!NT_STATUS_IS_OK(status
)) {
294 * @brief Create a new struct json_object, wrapping a JSON Object.
296 * Create a new json object, the json_object wraps the underlying json
297 * implementations JSON Object representation.
299 * Free with a call to json_free_object, note that the jansson implementation
300 * allocates memory with malloc and not talloc.
302 * @return a struct json_object, valid will be set to false if the object
303 * could not be created.
306 struct json_object
json_new_object(void) {
308 struct json_object object
= json_empty_object
;
310 object
.root
= json_object();
311 if (object
.root
== NULL
) {
312 object
.valid
= false;
313 DBG_ERR("Unable to create JSON object\n");
321 * @brief Create a new struct json_object wrapping a JSON Array.
323 * Create a new json object, the json_object wraps the underlying json
324 * implementations JSON Array representation.
326 * Free with a call to json_free_object, note that the jansson implementation
327 * allocates memory with malloc and not talloc.
329 * @return a struct json_object, error will be set to true if the array
330 * could not be created.
333 struct json_object
json_new_array(void) {
335 struct json_object array
= json_empty_object
;
337 array
.root
= json_array();
338 if (array
.root
== NULL
) {
340 DBG_ERR("Unable to create JSON array\n");
349 * @brief free and invalidate a previously created JSON object.
351 * Release any resources owned by a json_object, and then mark the structure
352 * as invalid. It is safe to call this multiple times on an object.
355 void json_free(struct json_object
*object
)
357 if (object
->root
!= NULL
) {
358 json_decref(object
->root
);
361 object
->valid
= false;
365 * @brief is the current JSON object invalid?
367 * Check the state of the object to determine if it is invalid.
369 * @return is the object valid?
372 bool json_is_invalid(const struct json_object
*object
)
374 return !object
->valid
;
378 * @brief Add an integer value to a JSON object.
380 * Add an integer value named 'name' to the json object.
382 * @param object the JSON object to be updated.
383 * @param name the name of the value.
384 * @param value the value.
386 * @return 0 the operation was successful
387 * -1 the operation failed
390 int json_add_int(struct json_object
*object
, const char *name
, const json_int_t value
)
393 json_t
*integer
= NULL
;
395 if (json_is_invalid(object
)) {
396 DBG_ERR("Unable to add int [%s] value [%jd], "
397 "target object is invalid\n",
403 integer
= json_integer(value
);
404 if (integer
== NULL
) {
405 DBG_ERR("Unable to create integer value [%s] value [%jd]\n",
411 ret
= json_object_set_new(object
->root
, name
, integer
);
413 json_decref(integer
);
414 DBG_ERR("Unable to add int [%s] value [%jd]\n",
422 * @brief Add a boolean value to a JSON object.
424 * Add a boolean value named 'name' to the json object.
426 * @param object the JSON object to be updated.
427 * @param name the name.
428 * @param value the value.
430 * @return 0 the operation was successful
431 * -1 the operation failed
434 int json_add_bool(struct json_object
*object
,
440 if (json_is_invalid(object
)) {
441 DBG_ERR("Unable to add boolean [%s] value [%d], "
442 "target object is invalid\n",
448 ret
= json_object_set_new(object
->root
, name
, json_boolean(value
));
450 DBG_ERR("Unable to add boolean [%s] value [%d]\n", name
, value
);
456 * @brief Add an optional boolean value to a JSON object.
458 * Add an optional boolean value named 'name' to the json object.
460 * @param object the JSON object to be updated.
461 * @param name the name.
462 * @param value the value.
464 * @return 0 the operation was successful
465 * -1 the operation failed
468 int json_add_optional_bool(struct json_object
*object
,
474 if (json_is_invalid(object
)) {
475 DBG_ERR("Unable to add boolean [%s] value [%d], "
476 "target object is invalid\n",
483 ret
= json_object_set_new(object
->root
, name
, json_boolean(*value
));
485 DBG_ERR("Unable to add boolean [%s] value [%d]\n", name
, *value
);
489 ret
= json_object_set_new(object
->root
, name
, json_null());
491 DBG_ERR("Unable to add null boolean [%s]\n", name
);
500 * @brief Add a string value to a JSON object.
502 * Add a string value named 'name' to the json object.
504 * @param object the JSON object to be updated.
505 * @param name the name.
506 * @param value the value.
508 * @return 0 the operation was successful
509 * -1 the operation failed
512 int json_add_string(struct json_object
*object
,
518 if (json_is_invalid(object
)) {
519 DBG_ERR("Unable to add string [%s], target object is invalid\n",
524 json_t
*string
= json_string(value
);
525 if (string
== NULL
) {
526 DBG_ERR("Unable to add string [%s], "
527 "could not create string object\n",
531 ret
= json_object_set_new(object
->root
, name
, string
);
534 DBG_ERR("Unable to add string [%s]\n", name
);
538 ret
= json_object_set_new(object
->root
, name
, json_null());
540 DBG_ERR("Unable to add null string [%s]\n", name
);
548 * @brief Assert that the current JSON object is an array.
550 * Check that the current object is a JSON array, and if not
551 * invalidate the object. We also log an error message as this indicates
552 * bug in the calling code.
554 * @param object the JSON object to be validated.
556 void json_assert_is_array(struct json_object
*array
) {
558 if (json_is_invalid(array
)) {
562 if (json_is_array(array
->root
) == false) {
563 DBG_ERR("JSON object is not an array\n");
564 array
->valid
= false;
570 * @brief Add a JSON object to a JSON object.
572 * Add a JSON object named 'name' to the json object.
574 * @param object the JSON object to be updated.
575 * @param name the name.
576 * @param value the value.
578 * @return 0 the operation was successful
579 * -1 the operation failed
582 int json_add_object(struct json_object
*object
,
584 struct json_object
*value
)
589 if (value
!= NULL
&& json_is_invalid(value
)) {
590 DBG_ERR("Invalid JSON object [%s] supplied\n", name
);
593 if (json_is_invalid(object
)) {
594 DBG_ERR("Unable to add object [%s], target object is invalid\n",
599 jv
= value
== NULL
? json_null() : value
->root
;
601 if (json_is_array(object
->root
)) {
602 ret
= json_array_append_new(object
->root
, jv
);
603 } else if (json_is_object(object
->root
)) {
604 ret
= json_object_set_new(object
->root
, name
, jv
);
606 DBG_ERR("Invalid JSON object type\n");
610 DBG_ERR("Unable to add object [%s]\n", name
);
616 * @brief Add a string to a JSON object, truncating if necessary.
619 * Add a string value named 'name' to the json object, the string will be
620 * truncated if it is more than len characters long. If len is 0 the value
621 * is encoded as a JSON null.
624 * @param object the JSON object to be updated.
625 * @param name the name.
626 * @param value the value.
627 * @param len the maximum number of characters to be copied.
629 * @return 0 the operation was successful
630 * -1 the operation failed
633 int json_add_stringn(struct json_object
*object
,
640 if (json_is_invalid(object
)) {
641 DBG_ERR("Unable to add string [%s], target object is invalid\n",
646 if (value
!= NULL
&& len
> 0) {
647 json_t
*string
= json_stringn(value
, len
);
648 if (string
== NULL
) {
649 DBG_ERR("Unable to add string [%s], "
650 "could not create string object\n",
654 ret
= json_object_set_new(object
->root
, name
, string
);
657 DBG_ERR("Unable to add string [%s]\n", name
);
661 ret
= json_object_set_new(object
->root
, name
, json_null());
663 DBG_ERR("Unable to add null string [%s]\n", name
);
671 * @brief Add a version object to a JSON object
673 * Add a version object to the JSON object
674 * "version":{"major":1, "minor":0}
676 * The version tag is intended to aid the processing of the JSON messages
677 * The major version number should change when an attribute is:
680 * - its meaning changes
681 * - its contents change format
682 * The minor version should change whenever a new attribute is added and for
683 * minor bug fixes to an attributes content.
686 * @param object the JSON object to be updated.
687 * @param major the major version number
688 * @param minor the minor version number
690 * @return 0 the operation was successful
691 * -1 the operation failed
693 int json_add_version(struct json_object
*object
, int major
, int minor
)
696 struct json_object version
;
698 if (json_is_invalid(object
)) {
699 DBG_ERR("Unable to add version, target object is invalid\n");
703 version
= json_new_object();
704 if (json_is_invalid(&version
)) {
705 DBG_ERR("Unable to add version, failed to create object\n");
708 ret
= json_add_int(&version
, "major", major
);
713 ret
= json_add_int(&version
, "minor", minor
);
718 ret
= json_add_object(object
, "version", &version
);
727 * @brief add an ISO 8601 timestamp to the object.
729 * Add a date and time as a timestamp in ISO 8601 format to a JSON object
731 * "time":"2017-03-06T17:18:04.455081+1300"
734 * @param object the JSON object to be updated.
735 * @param name the name.
736 * @param time the value to set.
738 * @return 0 the operation was successful
739 * -1 the operation failed
741 int json_add_time(struct json_object
*object
, const char *name
, const struct timeval tv
)
743 char buffer
[40]; /* formatted time less usec and timezone */
744 char timestamp
[65]; /* the formatted ISO 8601 time stamp */
745 char tz
[10]; /* formatted time zone */
746 struct tm
* tm_info
; /* current local time */
747 int ret
; /* return code from json operations */
749 if (json_is_invalid(object
)) {
750 DBG_ERR("Unable to add time, target object is invalid\n");
754 tm_info
= localtime(&tv
.tv_sec
);
755 if (tm_info
== NULL
) {
756 DBG_ERR("Unable to determine local time\n");
760 strftime(buffer
, sizeof(buffer
)-1, "%Y-%m-%dT%T", tm_info
);
761 strftime(tz
, sizeof(tz
)-1, "%z", tm_info
);
769 ret
= json_add_string(object
, name
, timestamp
);
771 DBG_ERR("Unable to add time to JSON object\n");
777 * @brief add an ISO 8601 timestamp to the object.
779 * Add the current date and time as a timestamp in ISO 8601 format
782 * "timestamp":"2017-03-06T17:18:04.455081+1300"
785 * @param object the JSON object to be updated.
787 * @return 0 the operation was successful
788 * -1 the operation failed
790 int json_add_timestamp(struct json_object
*object
)
792 struct timeval tv
; /* current system time */
793 int r
; /* response code from gettimeofday */
795 if (json_is_invalid(object
)) {
796 DBG_ERR("Unable to add time stamp, target object is invalid\n");
800 r
= gettimeofday(&tv
, NULL
);
802 DBG_ERR("Unable to get time of day: (%d) %s\n",
808 return json_add_time(object
, "timestamp", tv
);
812 *@brief Add a tsocket_address to a JSON object
814 * Add the string representation of a Samba tsocket_address to the object.
816 * "localAddress":"ipv6::::0"
819 * @param object the JSON object to be updated.
820 * @param name the name.
821 * @param address the tsocket_address.
823 * @return 0 the operation was successful
824 * -1 the operation failed
827 int json_add_address(struct json_object
*object
,
829 const struct tsocket_address
*address
)
833 if (json_is_invalid(object
)) {
834 DBG_ERR("Unable to add address [%s], "
835 "target object is invalid\n",
840 if (address
== NULL
) {
841 ret
= json_object_set_new(object
->root
, name
, json_null());
843 DBG_ERR("Unable to add null address [%s]\n", name
);
847 TALLOC_CTX
*ctx
= talloc_new(NULL
);
851 DBG_ERR("Out of memory adding address [%s]\n", name
);
855 s
= tsocket_address_string(address
, ctx
);
857 DBG_ERR("Out of memory adding address [%s]\n", name
);
861 ret
= json_add_string(object
, name
, s
);
864 "Unable to add address [%s] value [%s]\n", name
, s
);
874 * @brief Add a formatted string representation of a sid to a json object.
876 * Add the string representation of a Samba sid to the object.
881 * @param object the JSON object to be updated.
882 * @param name the name.
885 * @return 0 the operation was successful
886 * -1 the operation failed
889 int json_add_sid(struct json_object
*object
,
891 const struct dom_sid
*sid
)
895 if (json_is_invalid(object
)) {
896 DBG_ERR("Unable to add SID [%s], "
897 "target object is invalid\n",
903 ret
= json_object_set_new(object
->root
, name
, json_null());
905 DBG_ERR("Unable to add null SID [%s]\n", name
);
909 struct dom_sid_buf sid_buf
;
911 ret
= json_add_string(
912 object
, name
, dom_sid_str_buf(sid
, &sid_buf
));
914 DBG_ERR("Unable to add SID [%s] value [%s]\n",
924 * @brief Add a formatted string representation of a guid to a json object.
926 * Add the string representation of a Samba GUID to the object.
928 * "guid":"1fb9f2ee-2a4d-4bf8-af8b-cb9d4529a9ab"
931 * @param object the JSON object to be updated.
932 * @param name the name.
933 * @param guid the guid.
935 * @return 0 the operation was successful
936 * -1 the operation failed
940 int json_add_guid(struct json_object
*object
,
942 const struct GUID
*guid
)
947 if (json_is_invalid(object
)) {
948 DBG_ERR("Unable to add GUID [%s], "
949 "target object is invalid\n",
955 ret
= json_object_set_new(object
->root
, name
, json_null());
957 DBG_ERR("Unable to add null GUID [%s]\n", name
);
962 struct GUID_txt_buf guid_buff
;
964 guid_str
= GUID_buf_string(guid
, &guid_buff
);
965 ret
= json_add_string(object
, name
, guid_str
);
967 DBG_ERR("Unable to add GUID [%s] value [%s]\n",
977 * @brief Add a hex-formatted string representation of a 32-bit integer to a
980 * Add a hex-formatted string representation of a 32-bit flags integer to the
983 * "accountFlags":"0x12345678"
986 * @param object the JSON object to be updated.
987 * @param name the name.
988 * @param flags the flags.
990 * @return 0 the operation was successful
991 * -1 the operation failed
995 int json_add_flags32(struct json_object
*object
,
997 const uint32_t flags
)
1000 char buf
[sizeof("0x12345678")];
1002 if (json_is_invalid(object
)) {
1003 DBG_ERR("Unable to add flags [%s], "
1004 "target object is invalid\n",
1009 ret
= snprintf(buf
, sizeof (buf
), "0x%08X", flags
);
1010 if (ret
!= sizeof (buf
) - 1) {
1011 DBG_ERR("Unable to format flags [%s] value [0x%08X]\n",
1017 ret
= json_add_string(object
, name
, buf
);
1019 DBG_ERR("Unable to add flags [%s] value [%s]\n",
1028 * @brief Replaces the object for a given key with a given json object.
1030 * If key already exists, the value will be replaced. Otherwise the given
1031 * value will be added under the given key.
1033 * @param object the JSON object to be updated.
1034 * @param key the key which will be updated.
1035 * @param new_obj the new value object to be inserted.
1037 * @return 0 the operation was successful
1038 * -1 the operation failed (e.j. if one of the parameters is invalid)
1040 int json_update_object(struct json_object
*object
,
1042 struct json_object
*new_obj
)
1046 if (json_is_invalid(object
)) {
1047 DBG_ERR("Unable to update key [%s], "
1048 "target object is invalid\n",
1052 if (json_is_invalid(new_obj
)) {
1053 DBG_ERR("Unable to update key [%s], "
1054 "new object is invalid\n",
1060 DBG_ERR("Unable to add null String as key\n");
1064 ret
= json_object_set(object
->root
, key
, new_obj
->root
);
1066 DBG_ERR("Unable to update object\n");
1074 * @brief Convert a JSON object into a string
1076 * Convert the json object into a string suitable for printing on a log line,
1077 * i.e. with no embedded line breaks.
1079 * If the object is invalid it logs an error and returns NULL.
1081 * @param mem_ctx the talloc memory context owning the returned string
1082 * @param object the json object.
1084 * @return A string representation of the object or NULL if the object
1087 char *json_to_string(TALLOC_CTX
*mem_ctx
, const struct json_object
*object
)
1090 char *json_string
= NULL
;
1092 if (json_is_invalid(object
)) {
1093 DBG_ERR("Invalid JSON object, unable to convert to string\n");
1097 if (object
->root
== NULL
) {
1102 * json_dumps uses malloc, so need to call free(json) to release
1105 json
= json_dumps(object
->root
, 0);
1107 DBG_ERR("Unable to convert JSON object to string\n");
1111 json_string
= talloc_strdup(mem_ctx
, json
);
1112 if (json_string
== NULL
) {
1114 DBG_ERR("Unable to copy JSON object string to talloc string\n");
1123 * @brief get a json array named "name" from the json object.
1125 * Get the array attribute named name, creating it if it does not exist.
1127 * @param object the json object.
1128 * @param name the name of the array attribute
1130 * @return The array object, will be created if it did not exist.
1132 struct json_object
json_get_array(struct json_object
*object
, const char *name
)
1135 struct json_object array
= json_empty_object
;
1139 if (json_is_invalid(object
)) {
1140 DBG_ERR("Invalid JSON object, unable to get array [%s]\n",
1146 array
= json_new_array();
1147 if (json_is_invalid(&array
)) {
1148 DBG_ERR("Unable to create new array for [%s]\n", name
);
1152 a
= json_object_get(object
->root
, name
);
1157 ret
= json_array_extend(array
.root
, a
);
1159 DBG_ERR("Unable to get array [%s]\n", name
);
1168 * @brief get a json object named "name" from the json object.
1170 * Get the object attribute named name, creating it if it does not exist.
1172 * @param object the json object.
1173 * @param name the name of the object attribute
1175 * @return The object, will be created if it did not exist.
1177 struct json_object
json_get_object(struct json_object
*object
, const char *name
)
1180 struct json_object o
= json_new_object();
1184 if (json_is_invalid(&o
)) {
1185 DBG_ERR("Unable to get object [%s]\n", name
);
1190 if (json_is_invalid(object
)) {
1191 DBG_ERR("Invalid JSON object, unable to get object [%s]\n",
1197 v
= json_object_get(object
->root
, name
);
1201 ret
= json_object_update(o
.root
, v
);
1203 DBG_ERR("Unable to get object [%s]\n", name
);
1211 * @brief Return the JSON null object.
1213 * @return the JSON null object.
1215 _WARN_UNUSED_RESULT_
struct json_object
json_null_object(void)
1217 struct json_object object
= json_empty_object
;
1219 object
.root
= json_null();
1220 if (object
.root
!= NULL
) {
1221 object
.valid
= true;
1228 * @brief Create a JSON object from a structure containing audit information.
1230 * @param audit_info the audit information from which to create a JSON object.
1232 * @return the JSON object (which may be valid or not)
1236 struct json_object
json_from_audit_info(const struct authn_audit_info
*audit_info
)
1238 struct json_object object
= json_new_object();
1239 enum auth_event_id_type auth_event_id
;
1240 const struct auth_user_info_dc
*client_info
= NULL
;
1241 const char *policy_name
= NULL
;
1242 const char *silo_name
= NULL
;
1243 const bool *policy_enforced
= NULL
;
1244 NTSTATUS policy_status
;
1245 struct authn_int64_optional tgt_lifetime_mins
;
1246 const char *location
= NULL
;
1247 const char *audit_event
= NULL
;
1248 const char *audit_reason
= NULL
;
1251 if (json_is_invalid(&object
)) {
1255 auth_event_id
= authn_audit_info_event_id(audit_info
);
1256 rc
= json_add_int(&object
, "eventId", auth_event_id
);
1261 policy_name
= authn_audit_info_policy_name(audit_info
);
1262 rc
= json_add_string(&object
, "policyName", policy_name
);
1267 silo_name
= authn_audit_info_silo_name(audit_info
);
1268 rc
= json_add_string(&object
, "siloName", silo_name
);
1273 policy_enforced
= authn_audit_info_policy_enforced(audit_info
);
1274 rc
= json_add_optional_bool(&object
, "policyEnforced", policy_enforced
);
1279 policy_status
= authn_audit_info_policy_status(audit_info
);
1280 rc
= json_add_string(&object
, "status", nt_errstr(policy_status
));
1285 tgt_lifetime_mins
= authn_audit_info_policy_tgt_lifetime_mins(audit_info
);
1286 if (tgt_lifetime_mins
.is_present
) {
1287 rc
= json_add_int(&object
, "tgtLifetime", tgt_lifetime_mins
.val
);
1293 location
= authn_audit_info_location(audit_info
);
1294 rc
= json_add_string(&object
, "location", location
);
1299 audit_event
= authn_audit_info_event(audit_info
);
1300 rc
= json_add_string(&object
, "auditEvent", audit_event
);
1305 audit_reason
= authn_audit_info_reason(audit_info
);
1306 rc
= json_add_string(&object
, "reason", audit_reason
);
1311 client_info
= authn_audit_info_client_info(audit_info
);
1312 if (client_info
!= NULL
) {
1313 const struct auth_user_info
*client_user_info
= NULL
;
1315 client_user_info
= client_info
->info
;
1316 if (client_user_info
!= NULL
) {
1317 rc
= json_add_string(&object
, "checkedDomain", client_user_info
->domain_name
);
1322 rc
= json_add_string(&object
, "checkedAccount", client_user_info
->account_name
);
1327 rc
= json_add_string(&object
, "checkedLogonServer", client_user_info
->logon_server
);
1332 rc
= json_add_flags32(&object
, "checkedAccountFlags", client_user_info
->acct_flags
);
1338 if (client_info
->num_sids
) {
1339 const struct dom_sid
*policy_checked_sid
= NULL
;
1341 policy_checked_sid
= &client_info
->sids
[PRIMARY_USER_SID_INDEX
].sid
;
1342 rc
= json_add_sid(&object
, "checkedSid", policy_checked_sid
);