s4:rpc_server: Use generate_secret_buffer() to create a session key
[Samba.git] / lib / audit_logging / audit_logging.c
blob7d9c3b838b54a96adc1cb3045a92df5adcebb295
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:
25 #include "includes.h"
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);
58 if (ret != 0) {
59 DBG_ERR("Unable to get time of day: (%d) %s\n",
60 errno,
61 strerror(errno));
62 return NULL;
65 tm_info = localtime(&tv.tv_sec);
66 if (tm_info == NULL) {
67 DBG_ERR("Unable to determine local time\n");
68 return NULL;
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);
74 if (ts == NULL) {
75 DBG_ERR("Out of memory formatting time stamp\n");
77 return ts;
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,
91 const char* message,
92 int debug_class,
93 int debug_level)
95 DEBUGC(debug_class, debug_level, ("%s %s\n", prefix, message));
98 #ifdef HAVE_JANSSON
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,
113 int debug_class,
114 int debug_level)
116 TALLOC_CTX *frame = NULL;
117 char *s = NULL;
119 if (json_is_invalid(message)) {
120 DBG_ERR("Invalid JSON object, unable to log\n");
121 return;
124 frame = talloc_stackframe();
125 s = json_to_string(frame, message);
126 if (s == NULL) {
127 DBG_ERR("json_to_string returned NULL, "
128 "JSON audit message could not written\n");
129 TALLOC_FREE(frame);
130 return;
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));
141 TALLOC_FREE(frame);
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
153 * @return NTSTATUS
155 static NTSTATUS get_event_server(
156 struct imessaging_context *msg_ctx,
157 const char *server_name,
158 struct server_id *event_server)
160 NTSTATUS status;
161 TALLOC_CTX *frame = talloc_stackframe();
162 unsigned num_servers, i;
163 struct server_id *servers;
165 status = irpc_servers_byname(
166 msg_ctx,
167 frame,
168 server_name,
169 &num_servers,
170 &servers);
172 if (!NT_STATUS_IS_OK(status)) {
173 DBG_NOTICE(
174 "Failed to find '%s' registered on the message bus to "
175 "send JSON audit events to: %s\n",
176 server_name,
177 nt_errstr(status));
178 TALLOC_FREE(frame);
179 return status;
183 * Select the first server that is listening, because we get
184 * connection refused as NT_STATUS_OBJECT_NAME_NOT_FOUND
185 * without waiting
187 for (i = 0; i < num_servers; i++) {
188 status = imessaging_send(
189 msg_ctx,
190 servers[i],
191 MSG_PING,
192 &data_blob_null);
193 if (NT_STATUS_IS_OK(status)) {
194 *event_server = servers[i];
195 TALLOC_FREE(frame);
196 return NT_STATUS_OK;
199 DBG_NOTICE(
200 "Failed to find '%s' registered on the message bus to "
201 "send JSON audit events to: %s\n",
202 server_name,
203 nt_errstr(status));
204 TALLOC_FREE(frame);
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
220 * will be sent.
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 = {
233 .pid = 0,
235 NTSTATUS status;
237 const char *message_string = NULL;
238 DATA_BLOB message_blob = data_blob_null;
239 TALLOC_CTX *ctx = NULL;
241 if (json_is_invalid(message)) {
242 DBG_ERR("Invalid JSON object, unable to send\n");
243 return;
245 if (msg_ctx == NULL) {
246 DBG_DEBUG("No messaging context\n");
247 return;
250 ctx = talloc_new(NULL);
251 if (ctx == NULL) {
252 DBG_ERR("Out of memory creating temporary context\n");
253 return;
256 /* Need to refetch the address each time as the destination server may
257 * have disconnected and reconnected in the interim, in which case
258 * messages may get lost
260 status = get_event_server(msg_ctx, server_name, &event_server);
261 if (!NT_STATUS_IS_OK(status)) {
262 TALLOC_FREE(ctx);
263 return;
266 message_string = json_to_string(ctx, message);
267 message_blob = data_blob_string_const(message_string);
268 status = imessaging_send(
269 msg_ctx,
270 event_server,
271 message_type,
272 &message_blob);
275 * If the server crashed, try to find it again
277 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
278 status = get_event_server(msg_ctx, server_name, &event_server);
279 if (!NT_STATUS_IS_OK(status)) {
280 TALLOC_FREE(ctx);
281 return;
283 imessaging_send(
284 msg_ctx,
285 event_server,
286 message_type,
287 &message_blob);
289 TALLOC_FREE(ctx);
293 * @brief Create a new struct json_object, wrapping a JSON Object.
295 * Create a new json object, the json_object wraps the underlying json
296 * implementations JSON Object representation.
298 * Free with a call to json_free_object, note that the jansson inplementation
299 * allocates memory with malloc and not talloc.
301 * @return a struct json_object, valid will be set to false if the object
302 * could not be created.
305 struct json_object json_new_object(void) {
307 struct json_object object = json_empty_object;
309 object.root = json_object();
310 if (object.root == NULL) {
311 object.valid = false;
312 DBG_ERR("Unable to create JSON object\n");
313 return object;
315 object.valid = true;
316 return object;
320 * @brief Create a new struct json_object wrapping a JSON Array.
322 * Create a new json object, the json_object wraps the underlying json
323 * implementations JSON Array representation.
325 * Free with a call to json_free_object, note that the jansson inplementation
326 * allocates memory with malloc and not talloc.
328 * @return a struct json_object, error will be set to true if the array
329 * could not be created.
332 struct json_object json_new_array(void) {
334 struct json_object array = json_empty_object;
336 array.root = json_array();
337 if (array.root == NULL) {
338 array.valid = false;
339 DBG_ERR("Unable to create JSON array\n");
340 return array;
342 array.valid = true;
343 return array;
348 * @brief free and invalidate a previously created JSON object.
350 * Release any resources owned by a json_object, and then mark the structure
351 * as invalid. It is safe to call this multiple times on an object.
354 void json_free(struct json_object *object)
356 if (object->root != NULL) {
357 json_decref(object->root);
359 object->root = NULL;
360 object->valid = false;
364 * @brief is the current JSON object invalid?
366 * Check the state of the object to determine if it is invalid.
368 * @return is the object valid?
371 bool json_is_invalid(const struct json_object *object)
373 return !object->valid;
377 * @brief Add an integer value to a JSON object.
379 * Add an integer value named 'name' to the json object.
381 * @param object the JSON object to be updated.
382 * @param name the name of the value.
383 * @param value the value.
385 * @return 0 the operation was successful
386 * -1 the operation failed
389 int json_add_int(struct json_object *object, const char *name, const int value)
391 int ret = 0;
392 json_t *integer = NULL;
394 if (json_is_invalid(object)) {
395 DBG_ERR("Unable to add int [%s] value [%d], "
396 "target object is invalid\n",
397 name,
398 value);
399 return JSON_ERROR;
402 integer = json_integer(value);
403 if (integer == NULL) {
404 DBG_ERR("Unable to create integer value [%s] value [%d]\n",
405 name,
406 value);
407 return JSON_ERROR;
410 ret = json_object_set_new(object->root, name, integer);
411 if (ret != 0) {
412 json_decref(integer);
413 DBG_ERR("Unable to add int [%s] value [%d]\n", name, value);
415 return ret;
419 * @brief Add a boolean value to a JSON object.
421 * Add a boolean value named 'name' to the json object.
423 * @param object the JSON object to be updated.
424 * @param name the name.
425 * @param value the value.
427 * @return 0 the operation was successful
428 * -1 the operation failed
431 int json_add_bool(struct json_object *object,
432 const char *name,
433 const bool value)
435 int ret = 0;
437 if (json_is_invalid(object)) {
438 DBG_ERR("Unable to add boolean [%s] value [%d], "
439 "target object is invalid\n",
440 name,
441 value);
442 return JSON_ERROR;
445 ret = json_object_set_new(object->root, name, json_boolean(value));
446 if (ret != 0) {
447 DBG_ERR("Unable to add boolean [%s] value [%d]\n", name, value);
449 return ret;
453 * @brief Add a string value to a JSON object.
455 * Add a string value named 'name' to the json object.
457 * @param object the JSON object to be updated.
458 * @param name the name.
459 * @param value the value.
461 * @return 0 the operation was successful
462 * -1 the operation failed
465 int json_add_string(struct json_object *object,
466 const char *name,
467 const char *value)
469 int ret = 0;
471 if (json_is_invalid(object)) {
472 DBG_ERR("Unable to add string [%s], target object is invalid\n",
473 name);
474 return JSON_ERROR;
476 if (value) {
477 json_t *string = json_string(value);
478 if (string == NULL) {
479 DBG_ERR("Unable to add string [%s], "
480 "could not create string object\n",
481 name);
482 return JSON_ERROR;
484 ret = json_object_set_new(object->root, name, string);
485 if (ret != 0) {
486 json_decref(string);
487 DBG_ERR("Unable to add string [%s]\n", name);
488 return ret;
490 } else {
491 ret = json_object_set_new(object->root, name, json_null());
492 if (ret != 0) {
493 DBG_ERR("Unable to add null string [%s]\n", name);
494 return ret;
497 return ret;
501 * @brief Assert that the current JSON object is an array.
503 * Check that the current object is a JSON array, and if not
504 * invalidate the object. We also log an error message as this indicates
505 * bug in the calling code.
507 * @param object the JSON object to be validated.
509 void json_assert_is_array(struct json_object *array) {
511 if (json_is_invalid(array)) {
512 return;
515 if (json_is_array(array->root) == false) {
516 DBG_ERR("JSON object is not an array\n");
517 array->valid = false;
518 return;
523 * @brief Add a JSON object to a JSON object.
525 * Add a JSON object named 'name' to the json object.
527 * @param object the JSON object to be updated.
528 * @param name the name.
529 * @param value the value.
531 * @return 0 the operation was successful
532 * -1 the operation failed
535 int json_add_object(struct json_object *object,
536 const char *name,
537 struct json_object *value)
539 int ret = 0;
540 json_t *jv = NULL;
542 if (value != NULL && json_is_invalid(value)) {
543 DBG_ERR("Invalid JSON object [%s] supplied\n", name);
544 return JSON_ERROR;
546 if (json_is_invalid(object)) {
547 DBG_ERR("Unable to add object [%s], target object is invalid\n",
548 name);
549 return JSON_ERROR;
552 jv = value == NULL ? json_null() : value->root;
554 if (json_is_array(object->root)) {
555 ret = json_array_append_new(object->root, jv);
556 } else if (json_is_object(object->root)) {
557 ret = json_object_set_new(object->root, name, jv);
558 } else {
559 DBG_ERR("Invalid JSON object type\n");
560 ret = JSON_ERROR;
562 if (ret != 0) {
563 DBG_ERR("Unable to add object [%s]\n", name);
565 return ret;
569 * @brief Add a string to a JSON object, truncating if necessary.
572 * Add a string value named 'name' to the json object, the string will be
573 * truncated if it is more than len characters long. If len is 0 the value
574 * is encoded as a JSON null.
577 * @param object the JSON object to be updated.
578 * @param name the name.
579 * @param value the value.
580 * @param len the maximum number of characters to be copied.
582 * @return 0 the operation was successful
583 * -1 the operation failed
586 int json_add_stringn(struct json_object *object,
587 const char *name,
588 const char *value,
589 const size_t len)
592 int ret = 0;
593 if (json_is_invalid(object)) {
594 DBG_ERR("Unable to add string [%s], target object is invalid\n",
595 name);
596 return JSON_ERROR;
599 if (value != NULL && len > 0) {
600 json_t *string = NULL;
601 char buffer[len+1];
603 strncpy(buffer, value, len);
604 buffer[len] = '\0';
606 string = json_string(buffer);
607 if (string == NULL) {
608 DBG_ERR("Unable to add string [%s], "
609 "could not create string object\n",
610 name);
611 return JSON_ERROR;
613 ret = json_object_set_new(object->root, name, string);
614 if (ret != 0) {
615 json_decref(string);
616 DBG_ERR("Unable to add string [%s]\n", name);
617 return ret;
619 } else {
620 ret = json_object_set_new(object->root, name, json_null());
621 if (ret != 0) {
622 DBG_ERR("Unable to add null string [%s]\n", name);
623 return ret;
626 return ret;
630 * @brief Add a version object to a JSON object
632 * Add a version object to the JSON object
633 * "version":{"major":1, "minor":0}
635 * The version tag is intended to aid the processing of the JSON messages
636 * The major version number should change when an attribute is:
637 * - renamed
638 * - removed
639 * - its meaning changes
640 * - its contents change format
641 * The minor version should change whenever a new attribute is added and for
642 * minor bug fixes to an attributes content.
645 * @param object the JSON object to be updated.
646 * @param major the major version number
647 * @param minor the minor version number
649 * @return 0 the operation was successful
650 * -1 the operation failed
652 int json_add_version(struct json_object *object, int major, int minor)
654 int ret = 0;
655 struct json_object version;
657 if (json_is_invalid(object)) {
658 DBG_ERR("Unable to add version, target object is invalid\n");
659 return JSON_ERROR;
662 version = json_new_object();
663 if (json_is_invalid(&version)) {
664 DBG_ERR("Unable to add version, failed to create object\n");
665 return JSON_ERROR;
667 ret = json_add_int(&version, "major", major);
668 if (ret != 0) {
669 json_free(&version);
670 return ret;
672 ret = json_add_int(&version, "minor", minor);
673 if (ret != 0) {
674 json_free(&version);
675 return ret;
677 ret = json_add_object(object, "version", &version);
678 if (ret != 0) {
679 json_free(&version);
680 return ret;
682 return ret;
686 * @brief add an ISO 8601 timestamp to the object.
688 * Add the current date and time as a timestamp in ISO 8601 format
689 * to a JSON object
691 * "timestamp":"2017-03-06T17:18:04.455081+1300"
694 * @param object the JSON object to be updated.
696 * @return 0 the operation was successful
697 * -1 the operation failed
699 int json_add_timestamp(struct json_object *object)
701 char buffer[40]; /* formatted time less usec and timezone */
702 char timestamp[65]; /* the formatted ISO 8601 time stamp */
703 char tz[10]; /* formatted time zone */
704 struct tm* tm_info; /* current local time */
705 struct timeval tv; /* current system time */
706 int r; /* response code from gettimeofday */
707 int ret; /* return code from json operations */
709 if (json_is_invalid(object)) {
710 DBG_ERR("Unable to add time stamp, target object is invalid\n");
711 return JSON_ERROR;
714 r = gettimeofday(&tv, NULL);
715 if (r) {
716 DBG_ERR("Unable to get time of day: (%d) %s\n",
717 errno,
718 strerror(errno));
719 return JSON_ERROR;
722 tm_info = localtime(&tv.tv_sec);
723 if (tm_info == NULL) {
724 DBG_ERR("Unable to determine local time\n");
725 return JSON_ERROR;
728 strftime(buffer, sizeof(buffer)-1, "%Y-%m-%dT%T", tm_info);
729 strftime(tz, sizeof(tz)-1, "%z", tm_info);
730 snprintf(
731 timestamp,
732 sizeof(timestamp),
733 "%s.%06ld%s",
734 buffer,
735 tv.tv_usec,
736 tz);
737 ret = json_add_string(object, "timestamp", timestamp);
738 if (ret != 0) {
739 DBG_ERR("Unable to add time stamp to JSON object\n");
741 return ret;
745 *@brief Add a tsocket_address to a JSON object
747 * Add the string representation of a Samba tsocket_address to the object.
749 * "localAddress":"ipv6::::0"
752 * @param object the JSON object to be updated.
753 * @param name the name.
754 * @param address the tsocket_address.
756 * @return 0 the operation was successful
757 * -1 the operation failed
760 int json_add_address(struct json_object *object,
761 const char *name,
762 const struct tsocket_address *address)
764 int ret = 0;
766 if (json_is_invalid(object)) {
767 DBG_ERR("Unable to add address [%s], "
768 "target object is invalid\n",
769 name);
770 return JSON_ERROR;
773 if (address == NULL) {
774 ret = json_object_set_new(object->root, name, json_null());
775 if (ret != 0) {
776 DBG_ERR("Unable to add null address [%s]\n", name);
777 return JSON_ERROR;
779 } else {
780 TALLOC_CTX *ctx = talloc_new(NULL);
781 char *s = NULL;
783 if (ctx == NULL) {
784 DBG_ERR("Out of memory adding address [%s]\n", name);
785 return JSON_ERROR;
788 s = tsocket_address_string(address, ctx);
789 if (s == NULL) {
790 DBG_ERR("Out of memory adding address [%s]\n", name);
791 TALLOC_FREE(ctx);
792 return JSON_ERROR;
794 ret = json_add_string(object, name, s);
795 if (ret != 0) {
796 DBG_ERR(
797 "Unable to add address [%s] value [%s]\n", name, s);
798 TALLOC_FREE(ctx);
799 return JSON_ERROR;
801 TALLOC_FREE(ctx);
803 return ret;
807 * @brief Add a formatted string representation of a sid to a json object.
809 * Add the string representation of a Samba sid to the object.
811 * "sid":"S-1-5-18"
814 * @param object the JSON object to be updated.
815 * @param name the name.
816 * @param sid the sid
818 * @return 0 the operation was successful
819 * -1 the operation failed
822 int json_add_sid(struct json_object *object,
823 const char *name,
824 const struct dom_sid *sid)
826 int ret = 0;
828 if (json_is_invalid(object)) {
829 DBG_ERR("Unable to add SID [%s], "
830 "target object is invalid\n",
831 name);
832 return JSON_ERROR;
835 if (sid == NULL) {
836 ret = json_object_set_new(object->root, name, json_null());
837 if (ret != 0) {
838 DBG_ERR("Unable to add null SID [%s]\n", name);
839 return ret;
841 } else {
842 struct dom_sid_buf sid_buf;
844 ret = json_add_string(
845 object, name, dom_sid_str_buf(sid, &sid_buf));
846 if (ret != 0) {
847 DBG_ERR("Unable to add SID [%s] value [%s]\n",
848 name,
849 sid_buf.buf);
850 return ret;
853 return ret;
857 * @brief Add a formatted string representation of a guid to a json object.
859 * Add the string representation of a Samba GUID to the object.
861 * "guid":"1fb9f2ee-2a4d-4bf8-af8b-cb9d4529a9ab"
864 * @param object the JSON object to be updated.
865 * @param name the name.
866 * @param guid the guid.
868 * @return 0 the operation was successful
869 * -1 the operation failed
873 int json_add_guid(struct json_object *object,
874 const char *name,
875 const struct GUID *guid)
878 int ret = 0;
880 if (json_is_invalid(object)) {
881 DBG_ERR("Unable to add GUID [%s], "
882 "target object is invalid\n",
883 name);
884 return JSON_ERROR;
887 if (guid == NULL) {
888 ret = json_object_set_new(object->root, name, json_null());
889 if (ret != 0) {
890 DBG_ERR("Unable to add null GUID [%s]\n", name);
891 return ret;
893 } else {
894 char *guid_str;
895 struct GUID_txt_buf guid_buff;
897 guid_str = GUID_buf_string(guid, &guid_buff);
898 ret = json_add_string(object, name, guid_str);
899 if (ret != 0) {
900 DBG_ERR("Unable to guid GUID [%s] value [%s]\n",
901 name,
902 guid_str);
903 return ret;
906 return ret;
910 * @brief Convert a JSON object into a string
912 * Convert the jsom object into a string suitable for printing on a log line,
913 * i.e. with no embedded line breaks.
915 * If the object is invalid it logs an error and returns NULL.
917 * @param mem_ctx the talloc memory context owning the returned string
918 * @param object the json object.
920 * @return A string representation of the object or NULL if the object
921 * is invalid.
923 char *json_to_string(TALLOC_CTX *mem_ctx, const struct json_object *object)
925 char *json = NULL;
926 char *json_string = NULL;
928 if (json_is_invalid(object)) {
929 DBG_ERR("Invalid JSON object, unable to convert to string\n");
930 return NULL;
933 if (object->root == NULL) {
934 return NULL;
938 * json_dumps uses malloc, so need to call free(json) to release
939 * the memory
941 json = json_dumps(object->root, 0);
942 if (json == NULL) {
943 DBG_ERR("Unable to convert JSON object to string\n");
944 return NULL;
947 json_string = talloc_strdup(mem_ctx, json);
948 if (json_string == NULL) {
949 free(json);
950 DBG_ERR("Unable to copy JSON object string to talloc string\n");
951 return NULL;
953 free(json);
955 return json_string;
959 * @brief get a json array named "name" from the json object.
961 * Get the array attribute named name, creating it if it does not exist.
963 * @param object the json object.
964 * @param name the name of the array attribute
966 * @return The array object, will be created if it did not exist.
968 struct json_object json_get_array(struct json_object *object, const char *name)
971 struct json_object array = json_empty_object;
972 json_t *a = NULL;
973 int ret = 0;
975 if (json_is_invalid(object)) {
976 DBG_ERR("Invalid JSON object, unable to get array [%s]\n",
977 name);
978 json_free(&array);
979 return array;
982 array = json_new_array();
983 if (json_is_invalid(&array)) {
984 DBG_ERR("Unable to create new array for [%s]\n", name);
985 return array;
988 a = json_object_get(object->root, name);
989 if (a == NULL) {
990 return array;
993 ret = json_array_extend(array.root, a);
994 if (ret != 0) {
995 DBG_ERR("Unable to get array [%s]\n", name);
996 json_free(&array);
997 return array;
1000 return array;
1004 * @brief get a json object named "name" from the json object.
1006 * Get the object attribute named name, creating it if it does not exist.
1008 * @param object the json object.
1009 * @param name the name of the object attribute
1011 * @return The object, will be created if it did not exist.
1013 struct json_object json_get_object(struct json_object *object, const char *name)
1016 struct json_object o = json_new_object();
1017 json_t *v = NULL;
1018 int ret = 0;
1020 if (json_is_invalid(object)) {
1021 DBG_ERR("Invalid JSON object, unable to get object [%s]\n",
1022 name);
1023 json_free(&o);
1024 return o;
1027 v = json_object_get(object->root, name);
1028 if (v == NULL) {
1029 return o;
1031 ret = json_object_update(o.root, v);
1032 if (ret != 0) {
1033 DBG_ERR("Unable to get object [%s]\n", name);
1034 json_free(&o);
1035 return o;
1037 return o;
1039 #endif