X-Git-Url: https://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=blobdiff_plain;f=src%2Finterfaces%2Ftimedated%2Ftimedated.c;h=d5da851d59a05f9f495b02d6685f9a75f8569614;hp=c5d6bdf8bb87a208867c0452563828e35dfd98f1;hb=10ddceeb98322259fc13e3022ceeafc2191bb89d;hpb=03f12ac7edc62424667774b00fd250fe54879c29 diff --git a/src/interfaces/timedated/timedated.c b/src/interfaces/timedated/timedated.c index c5d6bdf..d5da851 100644 --- a/src/interfaces/timedated/timedated.c +++ b/src/interfaces/timedated/timedated.c @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -56,15 +57,109 @@ static struct timezone_checksum_pair tz_table[5000]; /* --- begin method/property/dbus signal code --- */ static gboolean -on_handle_set_time(Timedate1 *hn1_passed_interf, +on_handle_set_time(Timedate1 *td1_passed_interf, GDBusMethodInvocation *invoc, const gchar *greet, gpointer data) { - return FALSE; + + GVariant *params; + gint64 proposed_time, cur_time; + const gchar *bus_name; + gboolean policykit_auth; + check_auth_result is_authed; + gboolean relative; /* relative if passed time_t is meant to be added to current time */ + struct timespec new_time; + + params = g_dbus_method_invocation_get_parameters(invoc); + g_variant_get(params, "(xbb)", &proposed_time, &relative, &policykit_auth); + bus_name = g_dbus_method_invocation_get_sender(invoc); + + is_authed = polkit_try_auth(bus_name, "org.freedesktop.timedate1.set-time", policykit_auth); + + switch(is_authed) { + + case AUTHORIZED_NATIVELY: + case AUTHORIZED_BY_PROMPT: + break; + + case UNAUTHORIZED_NATIVELY: + case UNAUTHORIZED_FAILED_PROMPT: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.timedate1.Error.EACCES", "Insufficient permissions to set system time."); + return FALSE; + + case ERROR_BADBUS: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.timedate1.Error.EFAULT", "Provided bus name is invalid."); + return FALSE; + + case ERROR_BADACTION: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.timedate1.Error.EFAULT", "Provided action ID is invalid."); + return FALSE; + + case ERROR_GENERIC: + default: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.timedate1.Error.ECANCELED", "Failed to set system time for unknown reasons."); + return FALSE; + } + + if(!proposed_time) { + + timedate1_complete_set_time(td1_passed_interf, invoc); + return TRUE; + + } else if(relative) { + + cur_time = g_get_real_time(); + + if(proposed_time < 0 && cur_time + proposed_time > cur_time) { + + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.timedate1.Error.EINVAL", "Resultant time out of bounds."); + return FALSE; + + } else if(proposed_time > 0 && cur_time + proposed_time < cur_time) { + + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.timedate1.Error.EINVAL", "Resultant time out of bounds."); + return FALSE; + } + + new_time.tv_sec = (cur_time + proposed_time) / 1000000; + new_time.tv_nsec = CLAMP((((cur_time + proposed_time) % 1000000) * 1000), 0, 1000000000); + + if(!clock_settime(CLOCK_REALTIME, &new_time)) { + + timedate1_complete_set_time(td1_passed_interf, invoc); + return TRUE; + + } else { + + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.timedate1.Error.ECANCELED", "Failed to set system time for unknown reasons."); + return FALSE; + } + + } else if(proposed_time > 0) { + + new_time.tv_sec = (cur_time + proposed_time) / 1000000; + new_time.tv_nsec = CLAMP((((cur_time + proposed_time) % 1000000) * 1000), 0, 1000000000); + + if(!clock_settime(CLOCK_REALTIME, &new_time)) { + + timedate1_complete_set_time(td1_passed_interf, invoc); + return TRUE; + + } else { + + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.timedate1.Error.ECANCELED", "Failed to set system time for unknown reasons."); + return FALSE; + } + + } else { + + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.timedate1.Error.EINVAL", "Resultant time out of bounds."); + return FALSE; + } } static gboolean -on_handle_set_timezone(Timedate1 *hn1_passed_interf, +on_handle_set_timezone(Timedate1 *td1_passed_interf, GDBusMethodInvocation *invoc, const gchar *greet, gpointer data) { @@ -72,7 +167,7 @@ on_handle_set_timezone(Timedate1 *hn1_passed_interf, } static gboolean -on_handle_set_local_rtc(Timedate1 *hn1_passed_interf, +on_handle_set_local_rtc(Timedate1 *td1_passed_interf, GDBusMethodInvocation *invoc, const gchar *greet, gpointer data) { @@ -80,7 +175,7 @@ on_handle_set_local_rtc(Timedate1 *hn1_passed_interf, } static gboolean -on_handle_set_ntp(Timedate1 *hn1_passed_interf, +on_handle_set_ntp(Timedate1 *td1_passed_interf, GDBusMethodInvocation *invoc, const gchar *greet, gpointer data) {