From 32e9d7fa220d05f5ca95ed61cf6c7aa7d0261c03 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 21 Jan 2015 18:16:57 +0100 Subject: [PATCH] vfs_snapper: encode and decode Snapper DBus strings 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 Reviewed-by: Jeremy Allison --- 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 35f2a82c53b..b5e762887e8 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.11.4.GIT