#include "hostnamed-gen.h"
#include "hostnamed.h"
+#include "../../polkit-auth.h"
+
/* format: {
* (1) string to be matched against runtime machine's sysctl output.
* can be either the exact string or a substring contained
/* --- begin method/property/dbus signal code --- */
-/* TODO the extra boolean passed to these funcs is for policykit auth */
-/* TODO complete call with error, message, etc */
+/* TODO free some strings here */
static gboolean
on_handle_set_hostname(Hostname1 *hn1_passed_interf,
GDBusMethodInvocation *invoc,
gpointer data) {
GVariant *params;
gchar *proposed_hostname, *valid_hostname_buf;
- gboolean policykit_auth, ret;
+ const gchar *bus_name;
+ gboolean policykit_auth, ret, try_to_set;
size_t check_length;
+ check_auth_result is_authed;
proposed_hostname = NULL;
- ret = FALSE;
+ ret = try_to_set = FALSE;
params = g_dbus_method_invocation_get_parameters(invoc);
g_variant_get(params, "(sb)", &proposed_hostname, &policykit_auth);
+ bus_name = g_dbus_method_invocation_get_sender(invoc);
+
+ /* verify caller has correct permissions via polkit */
+ is_authed = polkit_try_auth(bus_name, "org.freedesktop.hostname1.SetHostname", policykit_auth);
+
+ switch(is_authed) {
+
+ case AUTHORIZED_NATIVELY:
+ case AUTHORIZED_BY_PROMPT:
+ try_to_set = TRUE;
+ break;
- if(proposed_hostname && (valid_hostname_buf = g_hostname_to_ascii(proposed_hostname))) {
+ case UNAUTHORIZED_NATIVELY:
+ case UNAUTHORIZED_FAILED_PROMPT:
+ g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.EACCES", "Insufficient permissions to set hostname.");
+ break;
+
+ case ERROR_BADBUS:
+ g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.EFAULT", "Provided bus name is invalid.");
+ break;
+
+ case ERROR_BADACTION:
+ g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.EFAULT", "Provided action ID is invalid.");
+ break;
+
+ case ERROR_GENERIC:
+ default:
+ g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.ECANCELED", "Failed to set hostname for unknown reason.");
+ break;
+ }
- check_length = strnlen(proposed_hostname, MAXHOSTNAMELEN + 1);
+ /* verify passed hostname's validity */
+ if(try_to_set && proposed_hostname && (valid_hostname_buf = g_hostname_to_ascii(proposed_hostname))) {
+
+ check_length = strnlen(valid_hostname_buf, MAXHOSTNAMELEN + 1);
+
+ if(check_length > MAXHOSTNAMELEN) {
- if(check_length > MAXHOSTNAMELEN)
g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.ENAMETOOLONG", "Hostname string exceeded maximum length.");
+ g_free(valid_hostname_buf);
+
+ } else if(sethostname(proposed_hostname, check_length)) {
+
+ g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.ECANCELED", "Failed to set hostname for unknown reason.");
+ g_free(valid_hostname_buf);
- else if(sethostname(proposed_hostname, check_length))
- g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.EACCES", "Insufficient permissions to change hostname.");
+ } else {
- else {
- HOSTNAME = proposed_hostname;
+ HOSTNAME = valid_hostname_buf;
hostname1_set_hostname(hn1_passed_interf, HOSTNAME);
+ g_ptr_array_add(hostnamed_freeable, valid_hostname_buf);
ret = TRUE;
hostname1_complete_set_hostname(hn1_passed_interf, invoc);
}
}
-
- if(proposed_hostname)
- g_free(proposed_hostname);
- if(valid_hostname_buf)
- g_free(valid_hostname_buf);
return ret;
}
/* --- end method/property/dbus signal code, begin bus/name handlers --- */
static void hostnamed_on_bus_acquired(GDBusConnection *conn,
- const gchar *name,
- gpointer user_data) {
+ const gchar *name,
+ gpointer user_data) {
g_printf("got bus/name, exporting %s's interface...\n", name);
CHASSIS = ICON = OS_CPENAME = 0;
KERN_NAME = KERN_RELEASE = KERN_VERS = 0;
HOSTNAME = STATIC_HOSTNAME = PRETTY_HOSTNAME = NULL;
-
+
set_signal_handlers();
if(!determine_chassis_and_icon() || !set_uname_properties() || !set_names())