s4:rpc_server: add dcesrv_call_session_info()
[Samba.git] / lib / audit_logging / audit_logging.c
blob6944da7f872ff34c9af5a2412f4faff5c9da5cdb
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 NTSTATUS status;
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");
241 return;
243 if (msg_ctx == NULL) {
244 DBG_DEBUG("No messaging context\n");
245 return;
248 ctx = talloc_new(NULL);
249 if (ctx == NULL) {
250 DBG_ERR("Out of memory creating temporary context\n");
251 return;
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)) {
260 TALLOC_FREE(ctx);
261 return;
264 message_string = json_to_string(ctx, message);
265 message_blob = data_blob_string_const(message_string);
266 status = imessaging_send(
267 msg_ctx,
268 event_server,
269 message_type,
270 &message_blob);
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)) {
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, 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");
311 return object;
313 object.valid = true;
314 return object;
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) {
336 array.valid = false;
337 DBG_ERR("Unable to create JSON array\n");
338 return array;
340 array.valid = true;
341 return array;
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);
357 object->root = NULL;
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)
389 int ret = 0;
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",
395 name,
396 value);
397 return JSON_ERROR;
400 integer = json_integer(value);
401 if (integer == NULL) {
402 DBG_ERR("Unable to create integer value [%s] value [%d]\n",
403 name,
404 value);
405 return JSON_ERROR;
408 ret = json_object_set_new(object->root, name, integer);
409 if (ret != 0) {
410 json_decref(integer);
411 DBG_ERR("Unable to add int [%s] value [%d]\n", name, value);
413 return ret;
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,
430 const char *name,
431 const bool value)
433 int ret = 0;
435 if (json_is_invalid(object)) {
436 DBG_ERR("Unable to add boolean [%s] value [%d], "
437 "target object is invalid\n",
438 name,
439 value);
440 return JSON_ERROR;
443 ret = json_object_set_new(object->root, name, json_boolean(value));
444 if (ret != 0) {
445 DBG_ERR("Unable to add boolean [%s] value [%d]\n", name, value);
447 return ret;
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,
464 const char *name,
465 const char *value)
467 int ret = 0;
469 if (json_is_invalid(object)) {
470 DBG_ERR("Unable to add string [%s], target object is invalid\n",
471 name);
472 return JSON_ERROR;
474 if (value) {
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",
479 name);
480 return JSON_ERROR;
482 ret = json_object_set_new(object->root, name, string);
483 if (ret != 0) {
484 json_decref(string);
485 DBG_ERR("Unable to add string [%s]\n", name);
486 return ret;
488 } else {
489 ret = json_object_set_new(object->root, name, json_null());
490 if (ret != 0) {
491 DBG_ERR("Unable to add null string [%s]\n", name);
492 return ret;
495 return ret;
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)) {
510 return;
513 if (json_is_array(array->root) == false) {
514 DBG_ERR("JSON object is not an array\n");
515 array->valid = false;
516 return;
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,
534 const char *name,
535 struct json_object *value)
537 int ret = 0;
538 json_t *jv = NULL;
540 if (value != NULL && json_is_invalid(value)) {
541 DBG_ERR("Invalid JSON object [%s] supplied\n", name);
542 return JSON_ERROR;
544 if (json_is_invalid(object)) {
545 DBG_ERR("Unable to add object [%s], target object is invalid\n",
546 name);
547 return JSON_ERROR;
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);
556 } else {
557 DBG_ERR("Invalid JSON object type\n");
558 ret = JSON_ERROR;
560 if (ret != 0) {
561 DBG_ERR("Unable to add object [%s]\n", name);
563 return ret;
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,
585 const char *name,
586 const char *value,
587 const size_t len)
590 int ret = 0;
591 if (json_is_invalid(object)) {
592 DBG_ERR("Unable to add string [%s], target object is invalid\n",
593 name);
594 return JSON_ERROR;
597 if (value != NULL && len > 0) {
598 json_t *string = NULL;
599 char buffer[len+1];
601 strncpy(buffer, value, len);
602 buffer[len] = '\0';
604 string = json_string(buffer);
605 if (string == NULL) {
606 DBG_ERR("Unable to add string [%s], "
607 "could not create string object\n",
608 name);
609 return JSON_ERROR;
611 ret = json_object_set_new(object->root, name, string);
612 if (ret != 0) {
613 json_decref(string);
614 DBG_ERR("Unable to add string [%s]\n", name);
615 return ret;
617 } else {
618 ret = json_object_set_new(object->root, name, json_null());
619 if (ret != 0) {
620 DBG_ERR("Unable to add null string [%s]\n", name);
621 return ret;
624 return ret;
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:
635 * - renamed
636 * - removed
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)
652 int ret = 0;
653 struct json_object version;
655 if (json_is_invalid(object)) {
656 DBG_ERR("Unable to add version, target object is invalid\n");
657 return JSON_ERROR;
660 version = json_new_object();
661 if (json_is_invalid(&version)) {
662 DBG_ERR("Unable to add version, failed to create object\n");
663 return JSON_ERROR;
665 ret = json_add_int(&version, "major", major);
666 if (ret != 0) {
667 json_free(&version);
668 return ret;
670 ret = json_add_int(&version, "minor", minor);
671 if (ret != 0) {
672 json_free(&version);
673 return ret;
675 ret = json_add_object(object, "version", &version);
676 if (ret != 0) {
677 json_free(&version);
678 return ret;
680 return ret;
684 * @brief add an ISO 8601 timestamp to the object.
686 * Add the current date and time as a timestamp in ISO 8601 format
687 * to a JSON object
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");
709 return JSON_ERROR;
712 r = gettimeofday(&tv, NULL);
713 if (r) {
714 DBG_ERR("Unable to get time of day: (%d) %s\n",
715 errno,
716 strerror(errno));
717 return JSON_ERROR;
720 tm_info = localtime(&tv.tv_sec);
721 if (tm_info == NULL) {
722 DBG_ERR("Unable to determine local time\n");
723 return JSON_ERROR;
726 strftime(buffer, sizeof(buffer)-1, "%Y-%m-%dT%T", tm_info);
727 strftime(tz, sizeof(tz)-1, "%z", tm_info);
728 snprintf(
729 timestamp,
730 sizeof(timestamp),
731 "%s.%06ld%s",
732 buffer,
733 tv.tv_usec,
734 tz);
735 ret = json_add_string(object, "timestamp", timestamp);
736 if (ret != 0) {
737 DBG_ERR("Unable to add time stamp to JSON object\n");
739 return ret;
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,
759 const char *name,
760 const struct tsocket_address *address)
762 int ret = 0;
764 if (json_is_invalid(object)) {
765 DBG_ERR("Unable to add address [%s], "
766 "target object is invalid\n",
767 name);
768 return JSON_ERROR;
771 if (address == NULL) {
772 ret = json_object_set_new(object->root, name, json_null());
773 if (ret != 0) {
774 DBG_ERR("Unable to add null address [%s]\n", name);
775 return JSON_ERROR;
777 } else {
778 TALLOC_CTX *ctx = talloc_new(NULL);
779 char *s = NULL;
781 if (ctx == NULL) {
782 DBG_ERR("Out of memory adding address [%s]\n", name);
783 return JSON_ERROR;
786 s = tsocket_address_string(address, ctx);
787 if (s == NULL) {
788 DBG_ERR("Out of memory adding address [%s]\n", name);
789 TALLOC_FREE(ctx);
790 return JSON_ERROR;
792 ret = json_add_string(object, name, s);
793 if (ret != 0) {
794 DBG_ERR(
795 "Unable to add address [%s] value [%s]\n", name, s);
796 TALLOC_FREE(ctx);
797 return JSON_ERROR;
799 TALLOC_FREE(ctx);
801 return ret;
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.
809 * "sid":"S-1-5-18"
812 * @param object the JSON object to be updated.
813 * @param name the name.
814 * @param sid the sid
816 * @return 0 the operation was successful
817 * -1 the operation failed
820 int json_add_sid(struct json_object *object,
821 const char *name,
822 const struct dom_sid *sid)
824 int ret = 0;
826 if (json_is_invalid(object)) {
827 DBG_ERR("Unable to add SID [%s], "
828 "target object is invalid\n",
829 name);
830 return JSON_ERROR;
833 if (sid == NULL) {
834 ret = json_object_set_new(object->root, name, json_null());
835 if (ret != 0) {
836 DBG_ERR("Unable to add null SID [%s]\n", name);
837 return ret;
839 } else {
840 struct dom_sid_buf sid_buf;
842 ret = json_add_string(
843 object, name, dom_sid_str_buf(sid, &sid_buf));
844 if (ret != 0) {
845 DBG_ERR("Unable to add SID [%s] value [%s]\n",
846 name,
847 sid_buf.buf);
848 return ret;
851 return ret;
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,
872 const char *name,
873 const struct GUID *guid)
876 int ret = 0;
878 if (json_is_invalid(object)) {
879 DBG_ERR("Unable to add GUID [%s], "
880 "target object is invalid\n",
881 name);
882 return JSON_ERROR;
885 if (guid == NULL) {
886 ret = json_object_set_new(object->root, name, json_null());
887 if (ret != 0) {
888 DBG_ERR("Unable to add null GUID [%s]\n", name);
889 return ret;
891 } else {
892 char *guid_str;
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);
897 if (ret != 0) {
898 DBG_ERR("Unable to guid GUID [%s] value [%s]\n",
899 name,
900 guid_str);
901 return ret;
904 return ret;
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
919 * is invalid.
921 char *json_to_string(TALLOC_CTX *mem_ctx, const struct json_object *object)
923 char *json = NULL;
924 char *json_string = NULL;
926 if (json_is_invalid(object)) {
927 DBG_ERR("Invalid JSON object, unable to convert to string\n");
928 return NULL;
931 if (object->root == NULL) {
932 return NULL;
936 * json_dumps uses malloc, so need to call free(json) to release
937 * the memory
939 json = json_dumps(object->root, 0);
940 if (json == NULL) {
941 DBG_ERR("Unable to convert JSON object to string\n");
942 return NULL;
945 json_string = talloc_strdup(mem_ctx, json);
946 if (json_string == NULL) {
947 free(json);
948 DBG_ERR("Unable to copy JSON object string to talloc string\n");
949 return NULL;
951 free(json);
953 return json_string;
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;
970 json_t *a = NULL;
971 int ret = 0;
973 if (json_is_invalid(object)) {
974 DBG_ERR("Invalid JSON object, unable to get array [%s]\n",
975 name);
976 json_free(&array);
977 return array;
980 array = json_new_array();
981 if (json_is_invalid(&array)) {
982 DBG_ERR("Unable to create new array for [%s]\n", name);
983 return array;
986 a = json_object_get(object->root, name);
987 if (a == NULL) {
988 return array;
991 ret = json_array_extend(array.root, a);
992 if (ret != 0) {
993 DBG_ERR("Unable to get array [%s]\n", name);
994 json_free(&array);
995 return array;
998 return array;
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();
1015 json_t *v = NULL;
1016 int ret = 0;
1018 if (json_is_invalid(object)) {
1019 DBG_ERR("Invalid JSON object, unable to get object [%s]\n",
1020 name);
1021 json_free(&o);
1022 return o;
1025 v = json_object_get(object->root, name);
1026 if (v == NULL) {
1027 return o;
1029 ret = json_object_update(o.root, v);
1030 if (ret != 0) {
1031 DBG_ERR("Unable to get object [%s]\n", name);
1032 json_free(&o);
1033 return o;
1035 return o;
1037 #endif