[PATCH 3/3] vfs_snapper: encode and decode Snapper DBus strings

David Disseldorp ddiss at samba.org
Wed Jan 21 10:16:57 MST 2015


Snapper uses a special character encoding for strings used in DBus
requests and responses. This change ensures that Samba packs and unpacks
strings in the corresponding format, using the previously added
encode/decode helper functions.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=11055

Signed-off-by: David Disseldorp <ddiss at samba.org>
---
 source3/modules/vfs_snapper.c | 110 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 94 insertions(+), 16 deletions(-)

diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index 35f2a82..b5e7628 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -319,12 +319,15 @@ static NTSTATUS snapper_type_check_get(DBusMessageIter *iter,
 	return NT_STATUS_OK;
 }
 
-static NTSTATUS snapper_dict_unpack(DBusMessageIter *iter,
+static NTSTATUS snapper_dict_unpack(TALLOC_CTX *mem_ctx,
+				    DBusMessageIter *iter,
 				    struct snapper_dict *dict_out)
 
 {
 	NTSTATUS status;
 	DBusMessageIter dct_iter;
+	char *key_encoded;
+	char *val_encoded;
 
 	status = snapper_type_check(iter, DBUS_TYPE_DICT_ENTRY);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -333,15 +336,25 @@ static NTSTATUS snapper_dict_unpack(DBusMessageIter *iter,
 	dbus_message_iter_recurse(iter, &dct_iter);
 
 	status = snapper_type_check_get(&dct_iter, DBUS_TYPE_STRING,
-					&dict_out->key);
+					&key_encoded);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+	status = snapper_dbus_str_decode(mem_ctx, key_encoded, &dict_out->key);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
 
 	dbus_message_iter_next(&dct_iter);
 	status = snapper_type_check_get(&dct_iter, DBUS_TYPE_STRING,
-					&dict_out->val);
+					&val_encoded);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(dict_out->key);
+		return status;
+	}
+	status = snapper_dbus_str_decode(mem_ctx, val_encoded, &dict_out->val);
 	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(dict_out->key);
 		return status;
 	}
 
@@ -384,7 +397,7 @@ static NTSTATUS snapper_dict_array_unpack(TALLOC_CTX *mem_ctx,
 		if (dicts == NULL)
 			abort();
 
-		status = snapper_dict_unpack(&array_iter,
+		status = snapper_dict_unpack(mem_ctx, &array_iter,
 					     &dicts[num_dicts - 1]);
 		if (!NT_STATUS_IS_OK(status)) {
 			talloc_free(dicts);
@@ -424,6 +437,8 @@ static NTSTATUS snapper_conf_unpack(TALLOC_CTX *mem_ctx,
 {
 	NTSTATUS status;
 	DBusMessageIter st_iter;
+	char *name_encoded;
+	char *mnt_encoded;
 
 	status = snapper_type_check(iter, DBUS_TYPE_STRUCT);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -432,15 +447,29 @@ static NTSTATUS snapper_conf_unpack(TALLOC_CTX *mem_ctx,
 	dbus_message_iter_recurse(iter, &st_iter);
 
 	status = snapper_type_check_get(&st_iter, DBUS_TYPE_STRING,
-					&conf_out->name);
+					&name_encoded);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	status = snapper_dbus_str_decode(mem_ctx, name_encoded,
+					 &conf_out->name);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
 
 	dbus_message_iter_next(&st_iter);
 	status = snapper_type_check_get(&st_iter, DBUS_TYPE_STRING,
-					&conf_out->mnt);
+					&mnt_encoded);
 	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(conf_out->name);
+		return status;
+	}
+
+	status = snapper_dbus_str_decode(mem_ctx, mnt_encoded,
+					 &conf_out->mnt);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(conf_out->name);
 		return status;
 	}
 
@@ -448,8 +477,13 @@ static NTSTATUS snapper_conf_unpack(TALLOC_CTX *mem_ctx,
 	status = snapper_dict_array_unpack(mem_ctx, &st_iter,
 					   &conf_out->num_attrs,
 					   &conf_out->attrs);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(conf_out->mnt);
+		talloc_free(conf_out->name);
+		return status;
+	}
 
-	return status;
+	return NT_STATUS_OK;
 }
 
 static struct snapper_conf *snapper_conf_array_base_find(int32_t num_confs,
@@ -577,11 +611,14 @@ static NTSTATUS snapper_list_confs_unpack(TALLOC_CTX *mem_ctx,
 	return NT_STATUS_OK;
 }
 
-static NTSTATUS snapper_list_snaps_pack(char *snapper_conf,
+static NTSTATUS snapper_list_snaps_pack(TALLOC_CTX *mem_ctx,
+					char *snapper_conf,
 					DBusMessage **req_msg_out)
 {
 	DBusMessage *msg;
 	DBusMessageIter args;
+	char *conf_encoded;
+	NTSTATUS status;
 
 	msg = dbus_message_new_method_call("org.opensuse.Snapper", /* target for the method call */
 					   "/org/opensuse/Snapper", /* object to call on */
@@ -592,10 +629,17 @@ static NTSTATUS snapper_list_snaps_pack(char *snapper_conf,
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	status = snapper_dbus_str_encode(mem_ctx, snapper_conf, &conf_encoded);
+	if (!NT_STATUS_IS_OK(status)) {
+		dbus_message_unref(msg);
+		return status;
+	}
+
 	/* append arguments */
 	dbus_message_iter_init_append(msg, &args);
 	if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,
-					    &snapper_conf)) {
+					    &conf_encoded)) {
+		talloc_free(conf_encoded);
 		dbus_message_unref(msg);
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -611,6 +655,8 @@ static NTSTATUS snapper_snap_struct_unpack(TALLOC_CTX *mem_ctx,
 {
 	NTSTATUS status;
 	DBusMessageIter st_iter;
+	char *desc_encoded;
+	char *cleanup_encoded;
 
 	status = snapper_type_check(iter, DBUS_TYPE_STRUCT);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -654,15 +700,29 @@ static NTSTATUS snapper_snap_struct_unpack(TALLOC_CTX *mem_ctx,
 
 	dbus_message_iter_next(&st_iter);
 	status = snapper_type_check_get(&st_iter, DBUS_TYPE_STRING,
-					&snap_out->desc);
+					&desc_encoded);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	status = snapper_dbus_str_decode(mem_ctx, desc_encoded,
+					 &snap_out->desc);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
 
 	dbus_message_iter_next(&st_iter);
 	status = snapper_type_check_get(&st_iter, DBUS_TYPE_STRING,
-					&snap_out->cleanup);
+					&cleanup_encoded);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(snap_out->desc);
+		return status;
+	}
+
+	status = snapper_dbus_str_decode(mem_ctx, cleanup_encoded,
+					 &snap_out->cleanup);
 	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(snap_out->desc);
 		return status;
 	}
 
@@ -670,8 +730,13 @@ static NTSTATUS snapper_snap_struct_unpack(TALLOC_CTX *mem_ctx,
 	status = snapper_dict_array_unpack(mem_ctx, &st_iter,
 					   &snap_out->num_user_data,
 					   &snap_out->user_data);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(snap_out->cleanup);
+		talloc_free(snap_out->desc);
+		return status;
+	}
 
-	return status;
+	return NT_STATUS_OK;
 }
 
 static void snapper_snap_array_print(int32_t num_snaps,
@@ -795,13 +860,16 @@ static NTSTATUS snapper_list_snaps_unpack(TALLOC_CTX *mem_ctx,
 	return NT_STATUS_OK;
 }
 
-static NTSTATUS snapper_list_snaps_at_time_pack(const char *snapper_conf,
+static NTSTATUS snapper_list_snaps_at_time_pack(TALLOC_CTX *mem_ctx,
+						const char *snapper_conf,
 						time_t time_lower,
 						time_t time_upper,
 						DBusMessage **req_msg_out)
 {
 	DBusMessage *msg;
 	DBusMessageIter args;
+	char *conf_encoded;
+	NTSTATUS status;
 
 	msg = dbus_message_new_method_call("org.opensuse.Snapper",
 					   "/org/opensuse/Snapper",
@@ -812,21 +880,30 @@ static NTSTATUS snapper_list_snaps_at_time_pack(const char *snapper_conf,
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	status = snapper_dbus_str_encode(mem_ctx, snapper_conf, &conf_encoded);
+	if (!NT_STATUS_IS_OK(status)) {
+		dbus_message_unref(msg);
+		return status;
+	}
+
 	dbus_message_iter_init_append(msg, &args);
 	if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,
-					    &snapper_conf)) {
+					    &conf_encoded)) {
+		talloc_free(conf_encoded);
 		dbus_message_unref(msg);
 		return NT_STATUS_NO_MEMORY;
 	}
 
 	if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_INT64,
 					    &time_lower)) {
+		talloc_free(conf_encoded);
 		dbus_message_unref(msg);
 		return NT_STATUS_NO_MEMORY;
 	}
 
 	if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_INT64,
 					    &time_upper)) {
+		talloc_free(conf_encoded);
 		dbus_message_unref(msg);
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -975,7 +1052,7 @@ static int snapper_get_shadow_copy_data(struct vfs_handle_struct *handle,
 		goto err_conn_free;
 	}
 
-	status = snapper_list_snaps_pack(conf_name, &req_msg);
+	status = snapper_list_snaps_pack(tmp_ctx, conf_name, &req_msg);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto err_conn_free;
 	}
@@ -1141,7 +1218,8 @@ static NTSTATUS snapper_get_snap_at_time_call(TALLOC_CTX *mem_ctx,
 	struct snapper_snap *snaps;
 	char *snap_path;
 
-	status = snapper_list_snaps_at_time_pack(conf_name,
+	status = snapper_list_snaps_at_time_pack(mem_ctx,
+						 conf_name,
 						 snaptime,
 						 snaptime,
 						 &req_msg);
-- 
2.1.2



More information about the samba-technical mailing list