ctdb-failover: Add failover configuration options
[Samba.git] / lib / audit_logging / audit_logging.c
blobac08863129a756f230f1a370e7352673b0331679
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 prefix Text to be printed at the start of the log line
109 * @param message The content of the log line.
110 * @param debub_class The debug class to log the message with.
111 * @param debug_level The debug level to log the message with.
113 void audit_log_json(const char* prefix,
114 struct json_object* message,
115 int debug_class,
116 int debug_level)
118 TALLOC_CTX *ctx = NULL;
119 char *s = NULL;
121 if (json_is_invalid(message)) {
122 DBG_ERR("Invalid JSON object, unable to log\n");
123 return;
126 ctx = talloc_new(NULL);
127 s = json_to_string(ctx, message);
128 if (s == NULL) {
129 DBG_ERR("json_to_string for (%s) returned NULL, "
130 "JSON audit message could not written\n",
131 prefix);
132 TALLOC_FREE(ctx);
133 return;
135 DEBUGC(debug_class, debug_level, ("JSON %s: %s\n", prefix, s));
136 TALLOC_FREE(ctx);
140 * @brief get a connection to the messaging event server.
142 * Get a connection to the messaging event server registered by server_name.
144 * @param msg_ctx a valid imessaging_context.
145 * @param server_name name of messaging event server to connect to.
146 * @param server_id The event server details to populate
148 * @return NTSTATUS
150 static NTSTATUS get_event_server(
151 struct imessaging_context *msg_ctx,
152 const char *server_name,
153 struct server_id *event_server)
155 NTSTATUS status;
156 TALLOC_CTX *frame = talloc_stackframe();
157 unsigned num_servers, i;
158 struct server_id *servers;
160 status = irpc_servers_byname(
161 msg_ctx,
162 frame,
163 server_name,
164 &num_servers,
165 &servers);
167 if (!NT_STATUS_IS_OK(status)) {
168 DBG_NOTICE(
169 "Failed to find '%s' registered on the message bus to "
170 "send JSON audit events to: %s\n",
171 server_name,
172 nt_errstr(status));
173 TALLOC_FREE(frame);
174 return status;
178 * Select the first server that is listening, because we get
179 * connection refused as NT_STATUS_OBJECT_NAME_NOT_FOUND
180 * without waiting
182 for (i = 0; i < num_servers; i++) {
183 status = imessaging_send(
184 msg_ctx,
185 servers[i],
186 MSG_PING,
187 &data_blob_null);
188 if (NT_STATUS_IS_OK(status)) {
189 *event_server = servers[i];
190 TALLOC_FREE(frame);
191 return NT_STATUS_OK;
194 DBG_NOTICE(
195 "Failed to find '%s' registered on the message bus to "
196 "send JSON audit events to: %s\n",
197 server_name,
198 nt_errstr(status));
199 TALLOC_FREE(frame);
200 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
204 * @brief send an audit message to a messaging event server.
206 * Send the message to a registered and listening event server.
207 * Note: Any errors are logged, and the message is not sent. This is to ensure
208 * that a poorly behaved event server does not impact Samba.
210 * As it is possible to lose messages, especially during server
211 * shut down, currently this function is primarily intended for use
212 * in integration tests.
214 * @param msg_ctx an imessaging_context, can be NULL in which case no message
215 * will be sent.
216 * @param server_name the naname of the event server to send the message to.
217 * @param messag_type A message type defined in librpc/idl/messaging.idl
218 * @param message The message to send.
221 void audit_message_send(
222 struct imessaging_context *msg_ctx,
223 const char *server_name,
224 uint32_t message_type,
225 struct json_object *message)
227 struct server_id event_server = {};
228 NTSTATUS status;
230 const char *message_string = NULL;
231 DATA_BLOB message_blob = data_blob_null;
232 TALLOC_CTX *ctx = NULL;
234 if (json_is_invalid(message)) {
235 DBG_ERR("Invalid JSON object, unable to send\n");
236 return;
238 if (msg_ctx == NULL) {
239 DBG_DEBUG("No messaging context\n");
240 return;
243 /* Need to refetch the address each time as the destination server may
244 * have disconnected and reconnected in the interim, in which case
245 * messages may get lost
247 status = get_event_server(msg_ctx, server_name, &event_server);
248 if (!NT_STATUS_IS_OK(status)) {
249 TALLOC_FREE(ctx);
250 return;
253 message_string = json_to_string(ctx, message);
254 message_blob = data_blob_string_const(message_string);
255 status = imessaging_send(
256 msg_ctx,
257 event_server,
258 message_type,
259 &message_blob);
262 * If the server crashed, try to find it again
264 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
265 status = get_event_server(msg_ctx, server_name, &event_server);
266 if (!NT_STATUS_IS_OK(status)) {
267 TALLOC_FREE(ctx);
268 return;
270 imessaging_send(
271 msg_ctx,
272 event_server,
273 message_type,
274 &message_blob);
276 TALLOC_FREE(ctx);
280 * @brief Create a new struct json_object, wrapping a JSON Object.
282 * Create a new json object, the json_object wraps the underlying json
283 * implementations JSON Object representation.
285 * Free with a call to json_free_object, note that the jansson inplementation
286 * allocates memory with malloc and not talloc.
288 * @return a struct json_object, valid will be set to false if the object
289 * could not be created.
292 struct json_object json_new_object(void) {
294 struct json_object object = json_empty_object;
296 object.root = json_object();
297 if (object.root == NULL) {
298 object.valid = false;
299 DBG_ERR("Unable to create JSON object\n");
300 return object;
302 object.valid = true;
303 return object;
307 * @brief Create a new struct json_object wrapping a JSON Array.
309 * Create a new json object, the json_object wraps the underlying json
310 * implementations JSON Array representation.
312 * Free with a call to json_free_object, note that the jansson inplementation
313 * allocates memory with malloc and not talloc.
315 * @return a struct json_object, error will be set to true if the array
316 * could not be created.
319 struct json_object json_new_array(void) {
321 struct json_object array = json_empty_object;
323 array.root = json_array();
324 if (array.root == NULL) {
325 array.valid = false;
326 DBG_ERR("Unable to create JSON array\n");
327 return array;
329 array.valid = true;
330 return array;
335 * @brief free and invalidate a previously created JSON object.
337 * Release any resources owned by a json_object, and then mark the structure
338 * as invalid. It is safe to call this multiple times on an object.
341 void json_free(struct json_object *object)
343 if (object->root != NULL) {
344 json_decref(object->root);
346 object->root = NULL;
347 object->valid = false;
351 * @brief is the current JSON object invalid?
353 * Check the state of the object to determine if it is invalid.
355 * @return is the object valid?
358 bool json_is_invalid(struct json_object *object)
360 return !object->valid;
364 * @brief Add an integer value to a JSON object.
366 * Add an integer value named 'name' to the json object.
368 * @param object the JSON object to be updated.
369 * @param name the name of the value.
370 * @param value the value.
372 * @return 0 the operation was successful
373 * -1 the operation failed
376 int json_add_int(struct json_object *object, const char *name, const int value)
378 int ret = 0;
379 json_t *integer = NULL;
381 if (json_is_invalid(object)) {
382 DBG_ERR("Unable to add int [%s] value [%d], "
383 "target object is invalid\n",
384 name,
385 value);
386 return JSON_ERROR;
389 integer = json_integer(value);
390 if (integer == NULL) {
391 DBG_ERR("Unable to create integer value [%s] value [%d]\n",
392 name,
393 value);
394 return JSON_ERROR;
397 ret = json_object_set_new(object->root, name, integer);
398 if (ret != 0) {
399 json_decref(integer);
400 DBG_ERR("Unable to add int [%s] value [%d]\n", name, value);
402 return ret;
406 * @brief Add a boolean value to a JSON object.
408 * Add a boolean value named 'name' to the json object.
410 * @param object the JSON object to be updated.
411 * @param name the name.
412 * @param value the value.
414 * @return 0 the operation was successful
415 * -1 the operation failed
418 int json_add_bool(struct json_object *object,
419 const char *name,
420 const bool value)
422 int ret = 0;
424 if (json_is_invalid(object)) {
425 DBG_ERR("Unable to add boolean [%s] value [%d], "
426 "target object is invalid\n",
427 name,
428 value);
429 return JSON_ERROR;
432 ret = json_object_set_new(object->root, name, json_boolean(value));
433 if (ret != 0) {
434 DBG_ERR("Unable to add boolean [%s] value [%d]\n", name, value);
436 return ret;
440 * @brief Add a string value to a JSON object.
442 * Add a string value named 'name' to the json object.
444 * @param object the JSON object to be updated.
445 * @param name the name.
446 * @param value the value.
448 * @return 0 the operation was successful
449 * -1 the operation failed
452 int json_add_string(struct json_object *object,
453 const char *name,
454 const char *value)
456 int ret = 0;
458 if (json_is_invalid(object)) {
459 DBG_ERR("Unable to add string [%s], target object is invalid\n",
460 name);
461 return JSON_ERROR;
463 if (value) {
464 json_t *string = json_string(value);
465 if (string == NULL) {
466 DBG_ERR("Unable to add string [%s], "
467 "could not create string object\n",
468 name);
469 return JSON_ERROR;
471 ret = json_object_set_new(object->root, name, string);
472 if (ret != 0) {
473 json_decref(string);
474 DBG_ERR("Unable to add string [%s]\n", name);
475 return ret;
477 } else {
478 ret = json_object_set_new(object->root, name, json_null());
479 if (ret != 0) {
480 DBG_ERR("Unable to add null string [%s]\n", name);
481 return ret;
484 return ret;
488 * @brief Assert that the current JSON object is an array.
490 * Check that the current object is a JSON array, and if not
491 * invalidate the object. We also log an error message as this indicates
492 * bug in the calling code.
494 * @param object the JSON object to be validated.
496 void json_assert_is_array(struct json_object *array) {
498 if (json_is_invalid(array)) {
499 return;
502 if (json_is_array(array->root) == false) {
503 DBG_ERR("JSON object is not an array\n");
504 array->valid = false;
505 return;
510 * @brief Add a JSON object to a JSON object.
512 * Add a JSON object named 'name' to the json object.
514 * @param object the JSON object to be updated.
515 * @param name the name.
516 * @param value the value.
518 * @return 0 the operation was successful
519 * -1 the operation failed
522 int json_add_object(struct json_object *object,
523 const char *name,
524 struct json_object *value)
526 int ret = 0;
527 json_t *jv = NULL;
529 if (value != NULL && json_is_invalid(value)) {
530 DBG_ERR("Invalid JSON object [%s] supplied\n", name);
531 return JSON_ERROR;
533 if (json_is_invalid(object)) {
534 DBG_ERR("Unable to add object [%s], target object is invalid\n",
535 name);
536 return JSON_ERROR;
539 jv = value == NULL ? json_null() : value->root;
541 if (json_is_array(object->root)) {
542 ret = json_array_append_new(object->root, jv);
543 } else if (json_is_object(object->root)) {
544 ret = json_object_set_new(object->root, name, jv);
545 } else {
546 DBG_ERR("Invalid JSON object type\n");
547 ret = JSON_ERROR;
549 if (ret != 0) {
550 DBG_ERR("Unable to add object [%s]\n", name);
552 return ret;
556 * @brief Add a string to a JSON object, truncating if necessary.
559 * Add a string value named 'name' to the json object, the string will be
560 * truncated if it is more than len characters long. If len is 0 the value
561 * is encoded as a JSON null.
564 * @param object the JSON object to be updated.
565 * @param name the name.
566 * @param value the value.
567 * @param len the maximum number of characters to be copied.
569 * @return 0 the operation was successful
570 * -1 the operation failed
573 int json_add_stringn(struct json_object *object,
574 const char *name,
575 const char *value,
576 const size_t len)
579 int ret = 0;
580 if (json_is_invalid(object)) {
581 DBG_ERR("Unable to add string [%s], target object is invalid\n",
582 name);
583 return JSON_ERROR;
586 if (value != NULL && len > 0) {
587 json_t *string = NULL;
588 char buffer[len+1];
590 strncpy(buffer, value, len);
591 buffer[len] = '\0';
593 string = json_string(buffer);
594 if (string == NULL) {
595 DBG_ERR("Unable to add string [%s], "
596 "could not create string object\n",
597 name);
598 return JSON_ERROR;
600 ret = json_object_set_new(object->root, name, string);
601 if (ret != 0) {
602 json_decref(string);
603 DBG_ERR("Unable to add string [%s]\n", name);
604 return ret;
606 } else {
607 ret = json_object_set_new(object->root, name, json_null());
608 if (ret != 0) {
609 DBG_ERR("Unable to add null string [%s]\n", name);
610 return ret;
613 return ret;
617 * @brief Add a version object to a JSON object
619 * Add a version object to the JSON object
620 * "version":{"major":1, "minor":0}
622 * The version tag is intended to aid the processing of the JSON messages
623 * The major version number should change when an attribute is:
624 * - renamed
625 * - removed
626 * - its meaning changes
627 * - its contents change format
628 * The minor version should change whenever a new attribute is added and for
629 * minor bug fixes to an attributes content.
632 * @param object the JSON object to be updated.
633 * @param major the major version number
634 * @param minor the minor version number
636 * @return 0 the operation was successful
637 * -1 the operation failed
639 int json_add_version(struct json_object *object, int major, int minor)
641 int ret = 0;
642 struct json_object version;
644 if (json_is_invalid(object)) {
645 DBG_ERR("Unable to add version, target object is invalid\n");
646 return JSON_ERROR;
649 version = json_new_object();
650 if (json_is_invalid(&version)) {
651 DBG_ERR("Unable to add version, failed to create object\n");
652 return JSON_ERROR;
654 ret = json_add_int(&version, "major", major);
655 if (ret != 0) {
656 json_free(&version);
657 return ret;
659 ret = json_add_int(&version, "minor", minor);
660 if (ret != 0) {
661 json_free(&version);
662 return ret;
664 ret = json_add_object(object, "version", &version);
665 if (ret != 0) {
666 json_free(&version);
667 return ret;
669 return ret;
673 * @brief add an ISO 8601 timestamp to the object.
675 * Add the current date and time as a timestamp in ISO 8601 format
676 * to a JSON object
678 * "timestamp":"2017-03-06T17:18:04.455081+1300"
681 * @param object the JSON object to be updated.
683 * @return 0 the operation was successful
684 * -1 the operation failed
686 int json_add_timestamp(struct json_object *object)
688 char buffer[40]; /* formatted time less usec and timezone */
689 char timestamp[65]; /* the formatted ISO 8601 time stamp */
690 char tz[10]; /* formatted time zone */
691 struct tm* tm_info; /* current local time */
692 struct timeval tv; /* current system time */
693 int r; /* response code from gettimeofday */
694 int ret; /* return code from json operations */
696 if (json_is_invalid(object)) {
697 DBG_ERR("Unable to add time stamp, target object is invalid\n");
698 return JSON_ERROR;
701 r = gettimeofday(&tv, NULL);
702 if (r) {
703 DBG_ERR("Unable to get time of day: (%d) %s\n",
704 errno,
705 strerror(errno));
706 return JSON_ERROR;
709 tm_info = localtime(&tv.tv_sec);
710 if (tm_info == NULL) {
711 DBG_ERR("Unable to determine local time\n");
712 return JSON_ERROR;
715 strftime(buffer, sizeof(buffer)-1, "%Y-%m-%dT%T", tm_info);
716 strftime(tz, sizeof(tz)-1, "%z", tm_info);
717 snprintf(
718 timestamp,
719 sizeof(timestamp),
720 "%s.%06ld%s",
721 buffer,
722 tv.tv_usec,
723 tz);
724 ret = json_add_string(object, "timestamp", timestamp);
725 if (ret != 0) {
726 DBG_ERR("Unable to add time stamp to JSON object\n");
728 return ret;
732 *@brief Add a tsocket_address to a JSON object
734 * Add the string representation of a Samba tsocket_address to the object.
736 * "localAddress":"ipv6::::0"
739 * @param object the JSON object to be updated.
740 * @param name the name.
741 * @param address the tsocket_address.
743 * @return 0 the operation was successful
744 * -1 the operation failed
747 int json_add_address(struct json_object *object,
748 const char *name,
749 const struct tsocket_address *address)
751 int ret = 0;
753 if (json_is_invalid(object)) {
754 DBG_ERR("Unable to add address [%s], "
755 "target object is invalid\n",
756 name);
757 return JSON_ERROR;
760 if (address == NULL) {
761 ret = json_object_set_new(object->root, name, json_null());
762 if (ret != 0) {
763 DBG_ERR("Unable to add null address [%s]\n", name);
764 return JSON_ERROR;
766 } else {
767 TALLOC_CTX *ctx = talloc_new(NULL);
768 char *s = NULL;
770 if (ctx == NULL) {
771 DBG_ERR("Out of memory adding address [%s]\n", name);
772 return JSON_ERROR;
775 s = tsocket_address_string(address, ctx);
776 if (s == NULL) {
777 DBG_ERR("Out of memory adding address [%s]\n", name);
778 TALLOC_FREE(ctx);
779 return JSON_ERROR;
781 ret = json_add_string(object, name, s);
782 if (ret != 0) {
783 DBG_ERR(
784 "Unable to add address [%s] value [%s]\n", name, s);
785 TALLOC_FREE(ctx);
786 return JSON_ERROR;
788 TALLOC_FREE(ctx);
790 return ret;
794 * @brief Add a formatted string representation of a sid to a json object.
796 * Add the string representation of a Samba sid to the object.
798 * "sid":"S-1-5-18"
801 * @param object the JSON object to be updated.
802 * @param name the name.
803 * @param sid the sid
805 * @return 0 the operation was successful
806 * -1 the operation failed
809 int json_add_sid(struct json_object *object,
810 const char *name,
811 const struct dom_sid *sid)
813 int ret = 0;
815 if (json_is_invalid(object)) {
816 DBG_ERR("Unable to add SID [%s], "
817 "target object is invalid\n",
818 name);
819 return JSON_ERROR;
822 if (sid == NULL) {
823 ret = json_object_set_new(object->root, name, json_null());
824 if (ret != 0) {
825 DBG_ERR("Unable to add null SID [%s]\n", name);
826 return ret;
828 } else {
829 char sid_buf[DOM_SID_STR_BUFLEN];
831 dom_sid_string_buf(sid, sid_buf, sizeof(sid_buf));
832 ret = json_add_string(object, name, sid_buf);
833 if (ret != 0) {
834 DBG_ERR("Unable to add SID [%s] value [%s]\n",
835 name,
836 sid_buf);
837 return ret;
840 return ret;
844 * @brief Add a formatted string representation of a guid to a json object.
846 * Add the string representation of a Samba GUID to the object.
848 * "guid":"1fb9f2ee-2a4d-4bf8-af8b-cb9d4529a9ab"
851 * @param object the JSON object to be updated.
852 * @param name the name.
853 * @param guid the guid.
855 * @return 0 the operation was successful
856 * -1 the operation failed
860 int json_add_guid(struct json_object *object,
861 const char *name,
862 const struct GUID *guid)
865 int ret = 0;
867 if (json_is_invalid(object)) {
868 DBG_ERR("Unable to add GUID [%s], "
869 "target object is invalid\n",
870 name);
871 return JSON_ERROR;
874 if (guid == NULL) {
875 ret = json_object_set_new(object->root, name, json_null());
876 if (ret != 0) {
877 DBG_ERR("Unable to add null GUID [%s]\n", name);
878 return ret;
880 } else {
881 char *guid_str;
882 struct GUID_txt_buf guid_buff;
884 guid_str = GUID_buf_string(guid, &guid_buff);
885 ret = json_add_string(object, name, guid_str);
886 if (ret != 0) {
887 DBG_ERR("Unable to guid GUID [%s] value [%s]\n",
888 name,
889 guid_str);
890 return ret;
893 return ret;
897 * @brief Convert a JSON object into a string
899 * Convert the jsom object into a string suitable for printing on a log line,
900 * i.e. with no embedded line breaks.
902 * If the object is invalid it logs an error and returns NULL.
904 * @param mem_ctx the talloc memory context owning the returned string
905 * @param object the json object.
907 * @return A string representation of the object or NULL if the object
908 * is invalid.
910 char *json_to_string(TALLOC_CTX *mem_ctx, struct json_object *object)
912 char *json = NULL;
913 char *json_string = NULL;
915 if (json_is_invalid(object)) {
916 DBG_ERR("Invalid JSON object, unable to convert to string\n");
917 return NULL;
920 if (object->root == NULL) {
921 return NULL;
925 * json_dumps uses malloc, so need to call free(json) to release
926 * the memory
928 json = json_dumps(object->root, 0);
929 if (json == NULL) {
930 DBG_ERR("Unable to convert JSON object to string\n");
931 return NULL;
934 json_string = talloc_strdup(mem_ctx, json);
935 if (json_string == NULL) {
936 free(json);
937 DBG_ERR("Unable to copy JSON object string to talloc string\n");
938 return NULL;
940 free(json);
942 return json_string;
946 * @brief get a json array named "name" from the json object.
948 * Get the array attribute named name, creating it if it does not exist.
950 * @param object the json object.
951 * @param name the name of the array attribute
953 * @return The array object, will be created if it did not exist.
955 struct json_object json_get_array(struct json_object *object, const char *name)
958 struct json_object array = json_empty_object;
959 json_t *a = NULL;
960 int ret = 0;
962 if (json_is_invalid(object)) {
963 DBG_ERR("Invalid JSON object, unable to get array [%s]\n",
964 name);
965 json_free(&array);
966 return array;
969 array = json_new_array();
970 if (json_is_invalid(&array)) {
971 DBG_ERR("Unable to create new array for [%s]\n", name);
972 return array;
975 a = json_object_get(object->root, name);
976 if (a == NULL) {
977 return array;
980 ret = json_array_extend(array.root, a);
981 if (ret != 0) {
982 DBG_ERR("Unable to get array [%s]\n", name);
983 json_free(&array);
984 return array;
987 return array;
991 * @brief get a json object named "name" from the json object.
993 * Get the object attribute named name, creating it if it does not exist.
995 * @param object the json object.
996 * @param name the name of the object attribute
998 * @return The object, will be created if it did not exist.
1000 struct json_object json_get_object(struct json_object *object, const char *name)
1003 struct json_object o = json_new_object();
1004 json_t *v = NULL;
1005 int ret = 0;
1007 if (json_is_invalid(object)) {
1008 DBG_ERR("Invalid JSON object, unable to get object [%s]\n",
1009 name);
1010 json_free(&o);
1011 return o;
1014 v = json_object_get(object->root, name);
1015 if (v == NULL) {
1016 return o;
1018 ret = json_object_update(o.root, v);
1019 if (ret != 0) {
1020 DBG_ERR("Unable to get object [%s]\n", name);
1021 json_free(&o);
1022 return o;
1024 return o;
1026 #endif