diff options
author | Robert Ancell <robert.ancell@canonical.com> | 2013-09-11 11:14:12 +1200 |
---|---|---|
committer | Robert Ancell <robert.ancell@canonical.com> | 2013-09-11 11:14:12 +1200 |
commit | 8d667243eb63f3891a49eea2c3495ff50736e069 (patch) | |
tree | a389996c70789bdec933ca212a58d5662e9e488c | |
parent | dd5dae15b5179c2a107203e6c98eabeb992bc592 (diff) | |
download | lightdm-8d667243eb63f3891a49eea2c3495ff50736e069.tar.gz |
For xauthority use open() with a mode instead of chmod() after the open that can be intercepted
-rw-r--r-- | src/x-authority.c | 72 |
1 files changed, 37 insertions, 35 deletions
diff --git a/src/x-authority.c b/src/x-authority.c index e9b42f82..8e986fc0 100644 --- a/src/x-authority.c +++ b/src/x-authority.c @@ -14,6 +14,8 @@ #include <errno.h> #include <unistd.h> #include <sys/stat.h> +#include <fcntl.h> +#include <glib/gstdio.h> #include "x-authority.h" @@ -210,26 +212,26 @@ read_string (gchar *data, gsize data_length, gsize *offset, gchar **value) return read_data (data, data_length, offset, length, (guint8 **) value); } -static void -write_uint16 (FILE *file, guint16 value) +static gboolean +write_uint16 (int fd, guint16 value) { guint8 v[2]; v[0] = value >> 8; v[1] = value & 0xFF; - fwrite (v, 2, 1, file); + return write (fd, v, 2) == 2; } -static void -write_data (FILE *file, const guint8 *value, gsize value_length) +static gboolean +write_data (int fd, const guint8 *value, gsize value_length) { - fwrite (value, value_length, 1, file); + return write (fd, value, value_length) == value_length; } -static void -write_string (FILE *file, const gchar *value) +static gboolean +write_string (int fd, const gchar *value) { - write_uint16 (file, strlen (value)); - write_data (file, (guint8 *) value, strlen (value)); + size_t value_length = strlen (value); + return write_uint16 (fd, value_length) && write_data (fd, (guint8 *) value, value_length); } gboolean @@ -239,9 +241,9 @@ x_authority_write (XAuthority *auth, XAuthWriteMode mode, const gchar *filename, gsize input_length = 0, input_offset = 0; GList *link, *records = NULL; XAuthority *a; - gboolean result; + gboolean result = TRUE; gboolean matched = FALSE; - FILE *output; + int output_fd; g_return_val_if_fail (auth != NULL, FALSE); g_return_val_if_fail (filename != NULL, FALSE); @@ -313,47 +315,47 @@ x_authority_write (XAuthority *auth, XAuthWriteMode mode, const gchar *filename, /* Write records back */ errno = 0; - output = fopen (filename, "w"); - if (output == NULL) + output_fd = g_open (filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + if (output_fd < 0) { g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), - "Failed to write X authority %s: %s", - filename, - g_strerror (errno)); - return FALSE; - } - - /* Only allow the file to be read by this user */ - if (chmod (filename, S_IRUSR | S_IWUSR) != 0) - { - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (errno), - "Failed to set permissions on X authority %s: %s", + "Failed to open X authority %s: %s", filename, g_strerror (errno)); return FALSE; } + errno = 0; for (link = records; link && result; link = link->next) { XAuthority *a = link->data; - write_uint16 (output, a->priv->family); - write_uint16 (output, a->priv->address_length); - write_data (output, a->priv->address, a->priv->address_length); - write_string (output, a->priv->number); - write_string (output, a->priv->authorization_name); - write_uint16 (output, a->priv->authorization_data_length); - write_data (output, a->priv->authorization_data, a->priv->authorization_data_length); + result = write_uint16 (output_fd, a->priv->family) && + write_uint16 (output_fd, a->priv->address_length) && + write_data (output_fd, a->priv->address, a->priv->address_length) && + write_string (output_fd, a->priv->number) && + write_string (output_fd, a->priv->authorization_name) && + write_uint16 (output_fd, a->priv->authorization_data_length) && + write_data (output_fd, a->priv->authorization_data, a->priv->authorization_data_length); g_object_unref (a); } g_list_free (records); - fclose (output); + close (output_fd); + + if (!result) + { + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errno), + "Failed to write X authority %s: %s", + filename, + g_strerror (errno)); + return FALSE; + } return TRUE; } |