summaryrefslogtreecommitdiff
path: root/lib/audit_logging
diff options
context:
space:
mode:
authorGary Lockyer <gary@catalyst.net.nz>2018-05-17 08:03:00 +1200
committerAndrew Bartlett <abartlet@samba.org>2018-06-01 08:28:26 +0200
commit77e66b86db606ff135c8c76a95c5576feec0fa51 (patch)
tree9da7d6b4189f665eae94caf6db2e5a7709b51c49 /lib/audit_logging
parent7a0d82b6948930506afd35c4d9fb7e7641adb8ba (diff)
downloadsamba-77e66b86db606ff135c8c76a95c5576feec0fa51.tar.gz
lib audit_logging: re-factor and add functions.
Re-factor the common calls to json_dumps DEBUGC and audit_message_send into a separate function. Add functions to retrieve json object and json array elements Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'lib/audit_logging')
-rw-r--r--lib/audit_logging/audit_logging.c114
-rw-r--r--lib/audit_logging/audit_logging.h24
-rw-r--r--lib/audit_logging/tests/audit_logging_test.c137
3 files changed, 264 insertions, 11 deletions
diff --git a/lib/audit_logging/audit_logging.c b/lib/audit_logging/audit_logging.c
index 5c16806d54e..1f82d576c84 100644
--- a/lib/audit_logging/audit_logging.c
+++ b/lib/audit_logging/audit_logging.c
@@ -102,9 +102,46 @@ char* audit_get_timestamp(TALLOC_CTX *frame)
return ts;
}
-#ifdef HAVE_JANSSON
+/*
+ * @brief write an audit message to the audit logs.
+ *
+ * Write a human readable text audit message to the samba logs.
+ *
+ * @param prefix Text to be printed at the start of the log line
+ * @param message The content of the log line.
+ * @param debub_class The debug class to log the message with.
+ * @param debug_level The debug level to log the message with.
+ */
+void audit_log_human_text(const char* prefix,
+ const char* message,
+ int debug_class,
+ int debug_level)
+{
+ DEBUGC(debug_class, debug_level, ("%s %s\n", prefix, message));
+}
-#include "system/time.h"
+#ifdef HAVE_JANSSON
+/*
+ * @brief write a json object to the samba audit logs.
+ *
+ * Write the json object to the audit logs as a formatted string
+ *
+ * @param prefix Text to be printed at the start of the log line
+ * @param message The content of the log line.
+ * @param debub_class The debug class to log the message with.
+ * @param debug_level The debug level to log the message with.
+ */
+void audit_log_json(
+ const char* prefix,
+ struct json_object* message,
+ int debug_class,
+ int debug_level)
+{
+ TALLOC_CTX *ctx = talloc_new(NULL);
+ char *s = json_to_string(ctx, message);
+ DEBUGC(debug_class, debug_level, ("JSON %s: %s\n", prefix, s));
+ TALLOC_FREE(ctx);
+}
/*
* @brief get a connection to the messaging event server.
@@ -192,14 +229,18 @@ void audit_message_send(
struct imessaging_context *msg_ctx,
const char *server_name,
uint32_t message_type,
- const char *message)
+ struct json_object *message)
{
struct server_id event_server;
NTSTATUS status;
- DATA_BLOB message_blob = data_blob_string_const(message);
+
+ const char *message_string = NULL;
+ DATA_BLOB message_blob = data_blob_null;
+ TALLOC_CTX *ctx = talloc_new(NULL);
if (msg_ctx == NULL) {
DBG_DEBUG("No messaging context\n");
+ TALLOC_FREE(ctx);
return;
}
@@ -213,9 +254,12 @@ void audit_message_send(
DBG_ERR("get_event_server for %s returned (%s)\n",
server_name,
nt_errstr(status));
+ TALLOC_FREE(ctx);
return;
}
+ message_string = json_to_string(ctx, message);
+ message_blob = data_blob_string_const(message_string);
status = imessaging_send(
msg_ctx,
event_server,
@@ -232,6 +276,7 @@ void audit_message_send(
DBG_ERR("get_event_server for %s returned (%s)\n",
server_name,
nt_errstr(status));
+ TALLOC_FREE(ctx);
return;
}
imessaging_send(
@@ -240,6 +285,7 @@ void audit_message_send(
message_type,
&message_blob);
}
+ TALLOC_FREE(ctx);
}
/*
@@ -768,4 +814,64 @@ char *json_to_string(TALLOC_CTX *mem_ctx, struct json_object *object)
return json_string;
}
+
+/*
+ * @brief get a json array named "name" from the json object.
+ *
+ * Get the array attribute named name, creating it if it does not exist.
+ *
+ * @param object the json object.
+ * @param name the name of the array attribute
+ *
+ * @return The array object, will be created if it did not exist.
+ */
+struct json_object json_get_array(struct json_object *object, const char* name)
+{
+
+ struct json_object array = json_new_array();
+ json_t *a = NULL;
+
+ if (object->error) {
+ array.error = true;
+ return array;
+ }
+
+ a = json_object_get(object->root, name);
+ if (a == NULL) {
+ return array;
+ }
+ json_array_extend(array.root, a);
+
+ return array;
+}
+
+/*
+ * @brief get a json object named "name" from the json object.
+ *
+ * Get the object attribute named name, creating it if it does not exist.
+ *
+ * @param object the json object.
+ * @param name the name of the object attribute
+ *
+ * @return The object, will be created if it did not exist.
+ */
+struct json_object json_get_object(struct json_object *object, const char* name)
+{
+
+ struct json_object o = json_new_object();
+ json_t *v = NULL;
+
+ if (object->error) {
+ o.error = true;
+ return o;
+ }
+
+ v = json_object_get(object->root, name);
+ if (v == NULL) {
+ return o;
+ }
+ json_object_update(o.root, v);
+
+ return o;
+}
#endif
diff --git a/lib/audit_logging/audit_logging.h b/lib/audit_logging/audit_logging.h
index 763f3ed5d9c..152b22ee916 100644
--- a/lib/audit_logging/audit_logging.h
+++ b/lib/audit_logging/audit_logging.h
@@ -21,14 +21,12 @@
#include "lib/messaging/irpc.h"
#include "lib/tsocket/tsocket.h"
-char* audit_get_timestamp(
- TALLOC_CTX *frame);
+char* audit_get_timestamp(TALLOC_CTX *frame);
+void audit_log_human_text(const char *prefix,
+ const char *message,
+ int debug_class,
+ int debug_level);
-void audit_message_send(
- struct imessaging_context *msg_ctx,
- const char *server_name,
- uint32_t message_type,
- const char *message);
#ifdef HAVE_JANSSON
#include <jansson.h>
/*
@@ -40,6 +38,14 @@ struct json_object {
bool error;
};
+void audit_log_json(const char *prefix,
+ struct json_object *message,
+ int debug_class,
+ int debug_level);
+void audit_message_send(struct imessaging_context *msg_ctx,
+ const char *server_name,
+ uint32_t message_type,
+ struct json_object *message);
struct json_object json_new_object(void);
struct json_object json_new_array(void);
void json_free(struct json_object *object);
@@ -85,5 +91,9 @@ void json_add_guid(
const char *name,
const struct GUID *guid);
+struct json_object json_get_array(struct json_object *object,
+ const char* name);
+struct json_object json_get_object(struct json_object *object,
+ const char* name);
char *json_to_string(TALLOC_CTX *mem_ctx, struct json_object *object);
#endif
diff --git a/lib/audit_logging/tests/audit_logging_test.c b/lib/audit_logging/tests/audit_logging_test.c
index 8385e9ce363..56e8fbcd43e 100644
--- a/lib/audit_logging/tests/audit_logging_test.c
+++ b/lib/audit_logging/tests/audit_logging_test.c
@@ -492,6 +492,141 @@ static void test_json_to_string(void **state)
}
#endif
+static void test_json_get_array(void **state)
+{
+ struct json_object object;
+ struct json_object array;
+ struct json_object stored_array = json_new_array();
+ json_t *value = NULL;
+ json_t *o = NULL;
+ struct json_object o1;
+ struct json_object o2;
+
+ object = json_new_object();
+
+ array = json_get_array(&object, "not-there");
+ assert_false(array.error);
+ assert_non_null(array.root);
+ assert_true(json_is_array(array.root));
+ json_free(&array);
+
+ o1 = json_new_object();
+ json_add_string(&o1, "value", "value-one");
+ json_add_object(&stored_array, NULL, &o1);
+ json_add_object(&object, "stored_array", &stored_array);
+
+ array = json_get_array(&object, "stored_array");
+ assert_false(array.error);
+ assert_non_null(array.root);
+ assert_true(json_is_array(array.root));
+
+ assert_int_equal(1, json_array_size(array.root));
+
+ o = json_array_get(array.root, 0);
+ assert_non_null(o);
+ assert_true(json_is_object(o));
+
+ value = json_object_get(o, "value");
+ assert_non_null(value);
+ assert_true(json_is_string(value));
+
+ assert_string_equal("value-one", json_string_value(value));
+ json_free(&array);
+
+ /*
+ * Now update the array and add it back to the object
+ */
+ array = json_get_array(&object, "stored_array");
+ assert_true(json_is_array(array.root));
+ o2 = json_new_object();
+ json_add_string(&o2, "value", "value-two");
+ assert_false(o2.error);
+ json_add_object(&array, NULL, &o2);
+ assert_true(json_is_array(array.root));
+ json_add_object(&object, "stored_array", &array);
+ assert_true(json_is_array(array.root));
+
+ array = json_get_array(&object, "stored_array");
+ assert_non_null(array.root);
+ assert_true(json_is_array(array.root));
+ assert_false(array.error);
+ assert_true(json_is_array(array.root));
+
+ assert_int_equal(2, json_array_size(array.root));
+
+ o = json_array_get(array.root, 0);
+ assert_non_null(o);
+ assert_true(json_is_object(o));
+
+ assert_non_null(value);
+ assert_true(json_is_string(value));
+
+ assert_string_equal("value-one", json_string_value(value));
+
+ o = json_array_get(array.root, 1);
+ assert_non_null(o);
+ assert_true(json_is_object(o));
+
+ value = json_object_get(o, "value");
+ assert_non_null(value);
+ assert_true(json_is_string(value));
+
+ assert_string_equal("value-two", json_string_value(value));
+
+ json_free(&array);
+ json_free(&object);
+}
+
+static void test_json_get_object(void **state)
+{
+ struct json_object object;
+ struct json_object o1;
+ struct json_object o2;
+ struct json_object o3;
+ json_t *value = NULL;
+
+ object = json_new_object();
+
+ o1 = json_get_object(&object, "not-there");
+ assert_false(o1.error);
+ assert_non_null(o1.root);
+ assert_true(json_is_object(o1.root));
+ json_free(&o1);
+
+ o1 = json_new_object();
+ json_add_string(&o1, "value", "value-one");
+ json_add_object(&object, "stored_object", &o1);
+
+ o2 = json_get_object(&object, "stored_object");
+ assert_false(o2.error);
+ assert_non_null(o2.root);
+ assert_true(json_is_object(o2.root));
+
+ value = json_object_get(o2.root, "value");
+ assert_non_null(value);
+ assert_true(json_is_string(value));
+
+ assert_string_equal("value-one", json_string_value(value));
+
+ json_add_string(&o2, "value", "value-two");
+ json_add_object(&object, "stored_object", &o2);
+
+
+ o3 = json_get_object(&object, "stored_object");
+ assert_false(o3.error);
+ assert_non_null(o3.root);
+ assert_true(json_is_object(o3.root));
+
+ value = json_object_get(o3.root, "value");
+ assert_non_null(value);
+ assert_true(json_is_string(value));
+
+ assert_string_equal("value-two", json_string_value(value));
+
+ json_free(&o3);
+ json_free(&object);
+}
+
static void test_audit_get_timestamp(void **state)
{
const char *t = NULL;
@@ -549,6 +684,8 @@ int main(int argc, const char **argv)
cmocka_unit_test(test_json_add_sid),
cmocka_unit_test(test_json_add_guid),
cmocka_unit_test(test_json_to_string),
+ cmocka_unit_test(test_json_get_array),
+ cmocka_unit_test(test_json_get_object),
#endif
cmocka_unit_test(test_audit_get_timestamp),
};