diff options
author | Ondrej Holy <oholy@redhat.com> | 2019-05-23 10:24:36 +0200 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2019-05-31 13:51:45 +0200 |
commit | 764e9af7522e3096c0f44613c330377d31c9bbb5 (patch) | |
tree | ad7b3a01fa16ba3b61f359d22a8bce98c83e5989 | |
parent | 00807221db383a78c788493c81c2f789fc482633 (diff) | |
download | gvfs-764e9af7522e3096c0f44613c330377d31c9bbb5.tar.gz |
admin: Add query_info_on_read/write functionality
Admin backend doesn't implement query_info_on_read/write which might
potentially lead to some race conditions which aren't really wanted
especially in case of admin backend. For example, in file_copy_fallback(),
g_file_query_info() is used if g_file_input_stream_query_info() is not
supported, which in theory means that the info might be obtained from
the different file then it is opened. Let's add this missing
functionality to prevent this possibility.
-rw-r--r-- | daemon/gvfsbackendadmin.c | 79 |
1 files changed, 67 insertions, 12 deletions
diff --git a/daemon/gvfsbackendadmin.c b/daemon/gvfsbackendadmin.c index 65a979e7..23d16f16 100644 --- a/daemon/gvfsbackendadmin.c +++ b/daemon/gvfsbackendadmin.c @@ -42,6 +42,8 @@ #include "gvfsjobopenforwrite.h" #include "gvfsjobqueryattributes.h" #include "gvfsjobqueryinfo.h" +#include "gvfsjobqueryinforead.h" +#include "gvfsjobqueryinfowrite.h" #include "gvfsjobread.h" #include "gvfsjobseekread.h" #include "gvfsjobseekwrite.h" @@ -156,6 +158,19 @@ complete_job (GVfsJob *job, } static void +fix_file_info (GFileInfo *info) +{ + /* Override read/write flags, since the above call will use access() + * to determine permissions, which does not honor our privileged + * capabilities. + */ + g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE); + g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE); + g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE); + g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE); +} + +static void do_query_info (GVfsBackend *backend, GVfsJobQueryInfo *query_info_job, const char *filename, @@ -180,19 +195,57 @@ do_query_info (GVfsBackend *backend, if (error != NULL) goto out; - /* Override read/write flags, since the above call will use access() - * to determine permissions, which does not honor our privileged - * capabilities. - */ - g_file_info_set_attribute_boolean (real_info, - G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE); - g_file_info_set_attribute_boolean (real_info, - G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, TRUE); - g_file_info_set_attribute_boolean (real_info, - G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, TRUE); - g_file_info_set_attribute_boolean (real_info, - G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME, TRUE); + fix_file_info (real_info); + g_file_info_copy_into (real_info, info); + g_object_unref (real_info); + + out: + complete_job (job, error); +} + +static void +do_query_info_on_read (GVfsBackend *backend, + GVfsJobQueryInfoRead *query_info_job, + GVfsBackendHandle handle, + GFileInfo *info, + GFileAttributeMatcher *matcher) +{ + GVfsJob *job = G_VFS_JOB (query_info_job); + GFileInputStream *stream = handle; + GError *error = NULL; + GFileInfo *real_info; + + real_info = g_file_input_stream_query_info (stream, query_info_job->attributes, + job->cancellable, &error); + if (error != NULL) + goto out; + + fix_file_info (real_info); + g_file_info_copy_into (real_info, info); + g_object_unref (real_info); + + out: + complete_job (job, error); +} + +static void +do_query_info_on_write (GVfsBackend *backend, + GVfsJobQueryInfoWrite *query_info_job, + GVfsBackendHandle handle, + GFileInfo *info, + GFileAttributeMatcher *matcher) +{ + GVfsJob *job = G_VFS_JOB (query_info_job); + GFileOutputStream *stream = handle; + GError *error = NULL; + GFileInfo *real_info; + + real_info = g_file_output_stream_query_info (stream, query_info_job->attributes, + job->cancellable, &error); + if (error != NULL) + goto out; + fix_file_info (real_info); g_file_info_copy_into (real_info, info); g_object_unref (real_info); @@ -868,6 +921,8 @@ g_vfs_backend_admin_class_init (GVfsBackendAdminClass * klass) backend_class->mount = do_mount; backend_class->open_for_read = do_open_for_read; backend_class->query_info = do_query_info; + backend_class->query_info_on_read = do_query_info_on_read; + backend_class->query_info_on_write = do_query_info_on_write; backend_class->read = do_read; backend_class->create = do_create; backend_class->append_to = do_append_to; |