[gnome-keyring/dbus-api] [gck] Write files without group or world permissions.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnome-keyring/dbus-api] [gck] Write files without group or world permissions.
- Date: Tue, 21 Jul 2009 00:37:37 +0000 (UTC)
commit deaae13e184dfd8141d454899af94f692231c66e
Author: Stef Walter <stef memberwebs com>
Date: Sun Jul 19 19:53:03 2009 +0000
[gck] Write files without group or world permissions.
Fixes bug #587908. Don't use g_file_set_contents() but write our
own routines for writing file data from a transaction.
pkcs11/gck/gck-transaction.c | 68 +++++++++++++++++++++++++++++++++++++----
1 files changed, 61 insertions(+), 7 deletions(-)
---
diff --git a/pkcs11/gck/gck-transaction.c b/pkcs11/gck/gck-transaction.c
index c441160..bab4733 100644
--- a/pkcs11/gck/gck-transaction.c
+++ b/pkcs11/gck/gck-transaction.c
@@ -27,6 +27,7 @@
#include <glib/gstdio.h>
#include <errno.h>
+#include <fcntl.h>
#include <string.h>
#include <unistd.h>
@@ -194,6 +195,62 @@ begin_link_temporary (GckTransaction *self, const gchar *filename)
g_assert_not_reached ();
}
+static gboolean
+write_sync_close (int fd, const guchar *data, gsize n_data)
+{
+ int res;
+
+ if (fd == -1)
+ return FALSE;
+
+ while (n_data > 0) {
+ res = write (fd, data, n_data);
+ if (res < 0) {
+ if (errno != EINTR && errno != EAGAIN) {
+ close (fd);
+ return FALSE;
+ }
+ }
+ n_data -= MAX (res, n_data);
+ }
+
+#ifdef HAVE_FSYNC
+ if (fsync (fd) < 0) {
+ close (fd);
+ return FALSE;
+ }
+#endif
+
+ if (close (fd) < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+write_to_file (const gchar *filename, const guchar *data, gsize n_data)
+{
+ gchar *dirname;
+ gchar *template;
+ gboolean result;
+
+ g_assert (filename);
+
+ dirname = g_path_get_dirname (filename);
+ template = g_build_filename (dirname, ".temp-XXXXXX", NULL);
+ g_free (dirname);
+
+ if (write_sync_close (g_mkstemp (template), data, n_data)) {
+ result = g_rename (template, filename) == 0;
+ } else {
+ g_unlink (template);
+ result = FALSE;
+ }
+
+ g_free (template);
+ return result;
+}
+
/* -----------------------------------------------------------------------------
* OBJECT
*/
@@ -396,15 +453,12 @@ void
gck_transaction_write_file (GckTransaction *self, const gchar *filename,
const guchar *data, gsize n_data)
{
- GError *error = NULL;
-
g_return_if_fail (GCK_IS_TRANSACTION (self));
g_return_if_fail (filename);
g_return_if_fail (data);
g_return_if_fail (!gck_transaction_get_failed (self));
- /* Open and lock the file */
-
+ /* Prepare file to be reverted */
if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
if (!begin_new_file (self, filename))
return;
@@ -413,9 +467,9 @@ gck_transaction_write_file (GckTransaction *self, const gchar *filename,
return;
}
- if (!g_file_set_contents (filename, (const gchar*)data, n_data, &error)) {
- g_warning ("couldn't write to file: %s: %s", filename,
- error && error->message ? error->message : "");
+ /* Put data in the expected place */
+ if (!write_to_file (filename, data, n_data)) {
+ g_warning ("couldn't write to file: %s: %s", filename, g_strerror (errno));
gck_transaction_fail (self, CKR_DEVICE_ERROR);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]