Send connman mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
https://lists.01.org/mailman/listinfo/connman
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."
Today's Topics:
1. [PATCH] timezone: Add support for setting timezone using
timedated (Philip Withnall)
2. Re: [PATCH] connman.service: Use ProtectSystem=true to allow
writing /etc/localtime (Philip Withnall)
----------------------------------------------------------------------
Message: 1
Date: Fri, 26 Aug 2016 12:02:45 +0100
From: Philip Withnall <[email protected]>
To: [email protected]
Subject: [PATCH] timezone: Add support for setting timezone using
timedated
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"
If we are running under systemd, the ProtectSystem key in our .service
file prevents us from writing to /etc/localtime. Instead, set the
timezone by using org.freedesktop.timedate1 over D-Bus, if it is
available. If it is not available, fall back to /etc/localtime.
Signed-off-by: Philip Withnall <[email protected]>
---
?src/timezone.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
?1 file changed, 210 insertions(+), 3 deletions(-)
diff --git a/src/timezone.c b/src/timezone.c
index e346b11..c74bfdd 100644
--- a/src/timezone.c
+++ b/src/timezone.c
@@ -38,11 +38,46 @@
?#include <glib.h>
?
?#include "connman.h"
+#include "gdbus.h"
?
?#define ETC_LOCALTIME "/etc/localtime"
?#define ETC_SYSCONFIG_CLOCK "/etc/sysconfig/clock"
?#define USR_SHARE_ZONEINFO "/usr/share/zoneinfo"
?
+/* See https://www.freedesktop.org/wiki/Software/systemd/timedated/ for
+ * reference. */
+#define TIMEDATED_SERVICE "org.freedesktop.timedate1"
+#define TIMEDATED_INTERFACE TIMEDATED_SERVICE
+#define TIMEDATED_PATH "/org/freedesktop/timedate1"
+
+static GDBusClient *timedated_client = NULL;
+static GDBusProxy *timedated_proxy = NULL;
+static gchar *timedated_timezone = NULL;
+
+static void timedate_property_changed(GDBusProxy *proxy, const char *name,
+ DBusMessageIter *iter, void *user_data)
+{
+ DBG("Property %s", name);
+
+ if (g_str_equal(name, "Timezone")) {
+ const char *str;
+
+ if (!iter) {
+ g_dbus_proxy_refresh_property(proxy, name);
+ return;
+ }
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
+ return;
+
+ dbus_message_iter_get_basic(iter, &str);
+ g_free(timedated_timezone);
+ timedated_timezone = g_strdup(str);
+
+ DBG("Timezone set to %s", timedated_timezone);
+ }
+}
+
?static char *read_key_file(const char *pathname, const char *key)
?{
? struct stat st;
@@ -226,7 +261,36 @@ static char *find_origin(void *src_map, struct stat
*src_st,
? return NULL;
?}
?
-char *__connman_timezone_lookup(void)
+/* Query the timezone from org.freedesktop.timedate1. */
+static char *__connman_timezone_lookup_dbus(void)
+{
+ DBusMessageIter iter;
+ const char *str;
+
+ DBG("");
+
+ /* If timedated_timezone is set, we have been notified of the timezone
+ ?* previously. */
+ if (timedated_proxy && timedated_timezone)
+ return timedated_timezone;
+
+ /* Not connected to the D-Bus service? */
+ if (!timedated_proxy)
+ return NULL;
+
+ /* Query D-Bus and update the cache. */
+ if (!g_dbus_proxy_get_property(timedated_proxy, "Timezone", &iter))
+ return NULL;
+ dbus_message_iter_get_basic(&iter, &str);
+
+ g_free(timedated_timezone);
+ timedated_timezone = g_strdup(str);
+
+ return g_strdup(timedated_timezone);
+}
+
+/* Look up the timezone from /etc/sysconfig/clock or /etc/localtime. */
+static char *__connman_timezone_lookup_filesystem(void)
?{
? struct stat st;
? void *map;
@@ -284,6 +348,20 @@ done:
? return zone;
?}
?
+char *__connman_timezone_lookup(void)
+{
+ char *timezone;
+
+ DBG("");
+
+ /* Try D-Bus first; then fall back to the filesystem. */
+ timezone = __connman_timezone_lookup_dbus();
+ if (timezone)
+ return timezone;
+
+ return __connman_timezone_lookup_filesystem();
+}
+
?static int write_file(void *src_map, struct stat *src_st, const char *pathname)
?{
? struct stat st;
@@ -311,7 +389,53 @@ static int write_file(void *src_map, struct stat *src_st,
const char *pathname)
? return 0;
?}
?
-int __connman_timezone_change(const char *zone)
+static void timezone_change_dbus_cb(DBusMessage *message, void *user_data)
+{
+ const char *zone = user_data;
+
+ if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
+ const char *dbus_error = dbus_message_get_error_name(message);
+
+ DBG("zone %s %s", zone, dbus_error);
+ } else {
+ DBG("zone %s success", zone);
+ }
+}
+
+static void timezone_change_dbus_append(DBusMessageIter *iter,
+ void *user_data)
+{
+ const char *zone = user_data;
+ dbus_bool_t user_interaction = FALSE;
+
+ /* The second parameter is user_interaction ? whether polkit should ask
+ ?* for credentials interactively if necessary. We do not want that.
+ ?*
+ ?* The polkit action controlling this is:
+ ?* org.freedesktop.timedate1.set-timezone. */
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &zone);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
&user_interaction);
+}
+
+/* Set the timezone using org.freedesktop.timedate1. */
+static int __connman_timezone_change_dbus(const char *zone)
+{
+ /* Are we connected to the D-Bus service? */
+ if (!timedated_proxy)
+ return -ENOENT;
+
+ DBG("zone %s", zone);
+
+ if (!g_dbus_proxy_method_call(timedated_proxy, "SetTimezone",
+ timezone_change_dbus_append, timezone_change_dbus_cb,
+ g_strdup(zone), g_free))
+ return -EIO;
+
+ return -EINPROGRESS;
+}
+
+/* Set the timezone by overwriting /etc/localtime. */
+static int __connman_timezone_change_filesystem(const char *zone)
?{
? struct stat st;
? char *map, pathname[PATH_MAX];
@@ -345,6 +469,23 @@ int __connman_timezone_change(const char *zone)
? return err;
?}
?
+int __connman_timezone_change(const char *zone)
+{
+ int err;
+
+ DBG("");
+
+ /* Try D-Bus first; then fall back to the filesystem. This order is
+ ?* important, as if we are running under systemd, /etc will be mounted
+ ?* read-only (due to the ProtectSystem key in our .service file), and
+ ?* hence only org.freedesktop.timedate1 can be used. */
+ err = __connman_timezone_change_dbus(zone);
+ if (err >= 0 || err == -EINPROGRESS)
+ return 0;
+
+ return __connman_timezone_change_filesystem(zone);
+}
+
?static guint inotify_watch = 0;
?
?static gboolean inotify_data(GIOChannel *channel, GIOCondition cond,
@@ -402,7 +543,45 @@ static gboolean inotify_data(GIOChannel *channel,
GIOCondition cond,
? return TRUE;
?}
?
-int __connman_timezone_init(void)
+static int __connman_timezone_init_dbus(void)
+{
+ DBusConnection *connection;
+ int err = -EIO;
+
+ DBG("");
+
+ /* Try connecting to org.freedesktop.timedate1 first. If that fails,
+ ?* try /etc/localtime as a fallback. */
+ connection = connman_dbus_get_connection();
+
+ timedated_client = g_dbus_client_new(connection, TIMEDATED_SERVICE,
+ TIMEDATED_PATH);
+ if (!timedated_client)
+ goto error;
+
+ timedated_proxy = g_dbus_proxy_new(timedated_client, TIMEDATED_PATH,
+ TIMEDATED_INTERFACE);
+ if (!timedated_proxy)
+ goto error;
+
+ g_dbus_proxy_set_property_watch(timedated_proxy,
+ timedate_property_changed, NULL);
+
+ dbus_connection_unref(connection);
+
+ return 0;
+error:
+ if (timedated_client) {
+ g_dbus_client_unref(timedated_client);
+ timedated_client = NULL;
+ }
+
+ dbus_connection_unref(connection);
+
+ return err;
+}
+
+static int __connman_timezone_init_filesystem(void)
?{
? GIOChannel *channel;
? char *dirname;
@@ -443,6 +622,21 @@ int __connman_timezone_init(void)
? return 0;
?}
?
+int __connman_timezone_init(void)
+{
+ int err;
+
+ DBG("");
+
+ /* Try connecting to org.freedesktop.timedate1 first. If that fails,
+ ?* try /etc/localtime as a fallback. */
+ err = __connman_timezone_init_dbus();
+ if (err >= 0)
+ return err;
+
+ return __connman_timezone_init_filesystem();
+}
+
?void __connman_timezone_cleanup(void)
?{
? DBG("");
@@ -451,4 +645,17 @@ void __connman_timezone_cleanup(void)
? g_source_remove(inotify_watch);
? inotify_watch = 0;
? }
+
+ if (timedated_proxy) {
+ g_dbus_proxy_unref(timedated_proxy);
+ timedated_proxy = NULL;
+ }
+
+ if (timedated_client) {
+ g_dbus_client_unref(timedated_client);
+ timedated_client = NULL;
+ }
+
+ g_free(timedated_timezone);
+ timedated_timezone = NULL;
?}
--?
2.7.4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL:
<http://lists.01.org/pipermail/connman/attachments/20160826/c9dbe511/attachment-0001.asc>
------------------------------
Message: 2
Date: Fri, 26 Aug 2016 12:03:15 +0100
From: Philip Withnall <[email protected]>
To: Patrik Flykt <[email protected]>, [email protected]
Subject: Re: [PATCH] connman.service: Use ProtectSystem=true to allow
writing /etc/localtime
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"
On Tue, 2016-08-23 at 13:22 +0300, Patrik Flykt wrote:
> On Mon, 2016-08-22 at 11:54 +0100, Philip Withnall wrote:
> >
> > I wonder if a better solution would be to use the
> > org.freedesktop.timedate1 interface to set the timezone via systemd.
> > On platforms which don't use systemd, we can continue to use the
> > existing /etc/localtime code, and we won't hit the ProtectSystem=full
> > problem.
>
> That sounds like a plan!
Updated patch sent in a new thread. Let?s abandon this thread.
Philip
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL:
<http://lists.01.org/pipermail/connman/attachments/20160826/e6c2adba/attachment-0001.asc>
------------------------------
Subject: Digest Footer
_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman
------------------------------
End of connman Digest, Vol 10, Issue 33
***************************************