diff options
-rw-r--r-- | conf/introspect-xml/hostnamed-ispect.xml | 10 | ||||
-rw-r--r-- | conf/polkit-policy/org.freedesktop.hostname1.policy | 18 | ||||
-rw-r--r-- | conf/service-files/org.freedesktop.hostname1.service | 4 | ||||
-rw-r--r-- | conf/service-files/org.freedesktop.locale1.service | 4 | ||||
-rw-r--r-- | conf/service-files/org.freedesktop.timedate1.service | 4 | ||||
-rw-r--r-- | doc/hostnamed-docbook.xml-org.freedesktop.hostname1.xml | 60 | ||||
-rw-r--r-- | src/interfaces/hostnamed/hostnamed.c | 155 |
7 files changed, 252 insertions, 3 deletions
diff --git a/conf/introspect-xml/hostnamed-ispect.xml b/conf/introspect-xml/hostnamed-ispect.xml index bca38cf..a67c306 100644 --- a/conf/introspect-xml/hostnamed-ispect.xml +++ b/conf/introspect-xml/hostnamed-ispect.xml @@ -9,6 +9,8 @@ <property name="PrettyHostname" type="s" access="read" /> <property name="IconName" type="s" access="read" /> <property name="Chassis" type="s" access="read" /> + <property name="Location" type="s" access="read" /> + <property name="Deployment" type="s" access="read" /> <property name="KernelName" type="s" access="read"> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const" /> </property> @@ -44,5 +46,13 @@ <arg type="s" direction="in" /> <arg type="b" direction="in" /> </method> + <method name="SetDeployment"> + <arg type="s" direction="in" /> + <arg type="b" direction="in" /> + </method> + <method name="SetLocation"> + <arg type="s" direction="in" /> + <arg type="b" direction="in" /> + </method> </interface> </node> diff --git a/conf/polkit-policy/org.freedesktop.hostname1.policy b/conf/polkit-policy/org.freedesktop.hostname1.policy index f80d57d..cc9fa99 100644 --- a/conf/polkit-policy/org.freedesktop.hostname1.policy +++ b/conf/polkit-policy/org.freedesktop.hostname1.policy @@ -54,4 +54,22 @@ <allow_active>auth_admin_keep</allow_active> </defaults> </action> + <action id="org.freedesktop.hostname1.set-deployment"> + <description>Set system's deployment.</description> + <message>Setting the system's deployment requires authentication.</message> + <defaults> + <allow_any>auth_admin_keep</allow_any> + <allow_inactive>auth_admin_keep</allow_inactive> + <allow_active>auth_admin_keep</allow_active> + </defaults> + </action> + <action id="org.freedesktop.hostname1.set-location"> + <description>Set system's location.</description> + <message>Setting the system's location requires authentication.</message> + <defaults> + <allow_any>auth_admin_keep</allow_any> + <allow_inactive>auth_admin_keep</allow_inactive> + <allow_active>auth_admin_keep</allow_active> + </defaults> + </action> </policyconfig> diff --git a/conf/service-files/org.freedesktop.hostname1.service b/conf/service-files/org.freedesktop.hostname1.service new file mode 100644 index 0000000..9f8e2e0 --- /dev/null +++ b/conf/service-files/org.freedesktop.hostname1.service @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.freedesktop.hostname1 +Exec=/usr/local/libexec/systemd/systemd-hostnamed +User=root diff --git a/conf/service-files/org.freedesktop.locale1.service b/conf/service-files/org.freedesktop.locale1.service new file mode 100644 index 0000000..9638a6f --- /dev/null +++ b/conf/service-files/org.freedesktop.locale1.service @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.freedesktop.locale1 +Exec=/usr/local/libexec/systemd/systemd-localed +User=root diff --git a/conf/service-files/org.freedesktop.timedate1.service b/conf/service-files/org.freedesktop.timedate1.service new file mode 100644 index 0000000..8477b5f --- /dev/null +++ b/conf/service-files/org.freedesktop.timedate1.service @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.freedesktop.timedate1 +Exec=/usr/local/libexec/systemd/systemd-timedated +User=root diff --git a/doc/hostnamed-docbook.xml-org.freedesktop.hostname1.xml b/doc/hostnamed-docbook.xml-org.freedesktop.hostname1.xml index 9626c46..7dc21df 100644 --- a/doc/hostnamed-docbook.xml-org.freedesktop.hostname1.xml +++ b/doc/hostnamed-docbook.xml-org.freedesktop.hostname1.xml @@ -18,6 +18,10 @@ IN b unnamed_arg1); <link linkend="gdbus-method-org-freedesktop-hostname1.SetChassis">SetChassis</link> (IN s unnamed_arg0, IN b unnamed_arg1); +<link linkend="gdbus-method-org-freedesktop-hostname1.SetDeployment">SetDeployment</link> (IN s unnamed_arg0, + IN b unnamed_arg1); +<link linkend="gdbus-method-org-freedesktop-hostname1.SetLocation">SetLocation</link> (IN s unnamed_arg0, + IN b unnamed_arg1); </synopsis> </refsynopsisdiv> <refsect1 role="properties"> @@ -28,6 +32,8 @@ <link linkend="gdbus-property-org-freedesktop-hostname1.PrettyHostname">PrettyHostname</link> readable s <link linkend="gdbus-property-org-freedesktop-hostname1.IconName">IconName</link> readable s <link linkend="gdbus-property-org-freedesktop-hostname1.Chassis">Chassis</link> readable s +<link linkend="gdbus-property-org-freedesktop-hostname1.Location">Location</link> readable s +<link linkend="gdbus-property-org-freedesktop-hostname1.Deployment">Deployment</link> readable s <link linkend="gdbus-property-org-freedesktop-hostname1.KernelName">KernelName</link> readable s <link linkend="gdbus-property-org-freedesktop-hostname1.KernelRelease">KernelRelease</link> readable s <link linkend="gdbus-property-org-freedesktop-hostname1.KernelVersion">KernelVersion</link> readable s @@ -136,6 +142,44 @@ SetChassis (IN s unnamed_arg0, </varlistentry> </variablelist> </refsect2> +<refsect2 role="method" id="gdbus-method-org-freedesktop-hostname1.SetDeployment"> + <title>The SetDeployment() method</title> + <indexterm zone="gdbus-method-org-freedesktop-hostname1.SetDeployment"><primary sortas="hostname1.SetDeployment">org.freedesktop.hostname1.SetDeployment()</primary></indexterm> +<programlisting> +SetDeployment (IN s unnamed_arg0, + IN b unnamed_arg1); +</programlisting> +<para></para> +<variablelist role="params"> +<varlistentry> + <term><literal>IN s <parameter>unnamed_arg0</parameter></literal>:</term> + <listitem><para></para></listitem> +</varlistentry> +<varlistentry> + <term><literal>IN b <parameter>unnamed_arg1</parameter></literal>:</term> + <listitem><para></para></listitem> +</varlistentry> +</variablelist> +</refsect2> +<refsect2 role="method" id="gdbus-method-org-freedesktop-hostname1.SetLocation"> + <title>The SetLocation() method</title> + <indexterm zone="gdbus-method-org-freedesktop-hostname1.SetLocation"><primary sortas="hostname1.SetLocation">org.freedesktop.hostname1.SetLocation()</primary></indexterm> +<programlisting> +SetLocation (IN s unnamed_arg0, + IN b unnamed_arg1); +</programlisting> +<para></para> +<variablelist role="params"> +<varlistentry> + <term><literal>IN s <parameter>unnamed_arg0</parameter></literal>:</term> + <listitem><para></para></listitem> +</varlistentry> +<varlistentry> + <term><literal>IN b <parameter>unnamed_arg1</parameter></literal>:</term> + <listitem><para></para></listitem> +</varlistentry> +</variablelist> +</refsect2> </refsect1> <refsect1 role="details" id="gdbus-properties-org.freedesktop.hostname1"> <title role="details.title">Property Details</title> @@ -179,6 +223,22 @@ Chassis readable s </programlisting> <para></para> </refsect2> +<refsect2 role="property" id="gdbus-property-org-freedesktop-hostname1.Location"> + <title>The "Location" property</title> + <indexterm zone="gdbus-property-org-freedesktop-hostname1.Location"><primary sortas="hostname1:Location">org.freedesktop.hostname1:Location</primary></indexterm> +<programlisting> +Location readable s +</programlisting> +<para></para> +</refsect2> +<refsect2 role="property" id="gdbus-property-org-freedesktop-hostname1.Deployment"> + <title>The "Deployment" property</title> + <indexterm zone="gdbus-property-org-freedesktop-hostname1.Deployment"><primary sortas="hostname1:Deployment">org.freedesktop.hostname1:Deployment</primary></indexterm> +<programlisting> +Deployment readable s +</programlisting> +<para></para> +</refsect2> <refsect2 role="property" id="gdbus-property-org-freedesktop-hostname1.KernelName"> <title>The "KernelName" property</title> <indexterm zone="gdbus-property-org-freedesktop-hostname1.KernelName"><primary sortas="hostname1:KernelName">org.freedesktop.hostname1:KernelName</primary></indexterm> diff --git a/src/interfaces/hostnamed/hostnamed.c b/src/interfaces/hostnamed/hostnamed.c index a320e2e..4201e48 100644 --- a/src/interfaces/hostnamed/hostnamed.c +++ b/src/interfaces/hostnamed/hostnamed.c @@ -84,6 +84,7 @@ gboolean dbus_interface_exported; /* reliable because of gdbus operational guara gchar *HOSTNAME, *STATIC_HOSTNAME, *PRETTY_HOSTNAME; gchar *CHASSIS, *ICON; gchar *KERN_NAME, *KERN_RELEASE, *KERN_VERS, *OS_CPENAME; +gchar *LOCATION = NULL, *DEPLOYMENT = NULL; /* TODO no specific vm or laptop icon in gnome * NOTE paravirtualization on xen is only available for linuxes right now @@ -113,6 +114,10 @@ const gchar *server_archs[] = { static const gchar *DEFAULT_DOMAIN = ""; /* blank domains are OK for now */ static const gchar *OS_HOSTNAME_PATH = "/etc/myname"; static const gchar *OS_CONFIG_PATH = "/etc/machine-info"; +/* XXX */ +static const guint LOCATION_MAXSIZE = 4096; +static const guint DEPLOYMENT_MAXSIZE = 4096; + /* --- begin method/property/dbus signal code --- */ @@ -513,6 +518,121 @@ on_handle_set_icon_name(Hostname1 *hn1_passed_interf, return ret; } +static gboolean +on_handle_set_location(Hostname1 *hn1_passed_interf, + GDBusMethodInvocation *invoc, + const gchar *greet, + gpointer data) { + GVariant *params; + const gchar *bus_name; + gchar *proposed_location, *valid_location_buf; + gboolean policykit_auth, ret, try_to_set; + check_auth_result is_authed; + + ret = try_to_set = FALSE; + + params = g_dbus_method_invocation_get_parameters(invoc); + g_variant_get(params, "(sb)", &proposed_location, &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.set-location", policykit_auth); + + switch(is_authed) { + + case AUTHORIZED_NATIVELY: + case AUTHORIZED_BY_PROMPT: + try_to_set = TRUE; + break; + + case UNAUTHORIZED_NATIVELY: + case UNAUTHORIZED_FAILED_PROMPT: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.EACCES", "Insufficient permissions to set location."); + return FALSE; + break; + + case ERROR_BADBUS: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.EFAULT", "Provided bus name is invalid."); + return FALSE; + break; + + case ERROR_BADACTION: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.EFAULT", "Provided action ID is invalid."); + return FALSE; + break; + + case ERROR_GENERIC: + default: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.ECANCELED", "Failed to set location for unknown reason."); + return FALSE; + break; + } + /* XXX follow systemd impl here */ + LOCATION = (gchar *) g_malloc0(LOCATION_MAXSIZE); + g_strlcpy(LOCATION, proposed_location, LOCATION_MAXSIZE); + hostname1_set_location(hn1_passed_interf, LOCATION); + g_ptr_array_add(hostnamed_freeable, valid_location_buf); + hostname1_complete_set_location(hn1_passed_interf, invoc); + return TRUE; +} + +static gboolean +on_handle_set_deployment(Hostname1 *hn1_passed_interf, + GDBusMethodInvocation *invoc, + const gchar *greet, + gpointer data) { + GVariant *params; + const gchar *bus_name; + gchar *proposed_deployment, *valid_deployment_buf; + gboolean policykit_auth, ret, try_to_set; + check_auth_result is_authed; + + ret = try_to_set = FALSE; + + params = g_dbus_method_invocation_get_parameters(invoc); + g_variant_get(params, "(sb)", &proposed_deployment, &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.set-deployment", policykit_auth); + + switch(is_authed) { + + case AUTHORIZED_NATIVELY: + case AUTHORIZED_BY_PROMPT: + try_to_set = TRUE; + break; + + case UNAUTHORIZED_NATIVELY: + case UNAUTHORIZED_FAILED_PROMPT: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.EACCES", "Insufficient permissions to set deployment."); + return FALSE; + break; + + case ERROR_BADBUS: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.EFAULT", "Provided bus name is invalid."); + return FALSE; + break; + + case ERROR_BADACTION: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.EFAULT", "Provided action ID is invalid."); + return FALSE; + break; + + case ERROR_GENERIC: + default: + g_dbus_method_invocation_return_dbus_error(invoc, "org.freedesktop.hostname1.Error.ECANCELED", "Failed to set deployment for unknown reason."); + return FALSE; + break; + } + /* XXX follow systemd impl here */ + DEPLOYMENT = (gchar *) g_malloc0(DEPLOYMENT_MAXSIZE); + g_strlcpy(DEPLOYMENT, proposed_deployment, DEPLOYMENT_MAXSIZE); + hostname1_set_deployment(hn1_passed_interf, DEPLOYMENT); + g_ptr_array_add(hostnamed_freeable, valid_deployment_buf); + hostname1_complete_set_deployment(hn1_passed_interf, invoc); + return TRUE; +} /* note: all hostnamed/hostname1's properties are read-only, * and do not need set_ functions, gdbus-codegen realized @@ -620,6 +740,21 @@ our_get_os_pretty_name() { return "OpenBSD"; } +const gchar * +our_get_location() { + + if(LOCATION) + return LOCATION; + return ""; +} + +const gchar * +our_get_deployment() { + + if(DEPLOYMENT) + return DEPLOYMENT; + return ""; +} /* --- end method/property/dbus signal code, begin bus/name handlers --- */ static void hostnamed_on_bus_acquired(GDBusConnection *conn, @@ -636,6 +771,8 @@ static void hostnamed_on_bus_acquired(GDBusConnection *conn, g_signal_connect(hostnamed_interf, "handle-set-pretty-hostname", G_CALLBACK(on_handle_set_pretty_hostname), NULL); g_signal_connect(hostnamed_interf, "handle-set-chassis", G_CALLBACK(on_handle_set_chassis), NULL); g_signal_connect(hostnamed_interf, "handle-set-icon-name", G_CALLBACK(on_handle_set_icon_name), NULL); + g_signal_connect(hostnamed_interf, "handle-set-deployment", G_CALLBACK(on_handle_set_deployment), NULL); + g_signal_connect(hostnamed_interf, "handle-set-location", G_CALLBACK(on_handle_set_location), NULL); /* set our properties before export */ hostname1_set_hostname(hostnamed_interf, our_get_hostname()); @@ -648,6 +785,9 @@ static void hostnamed_on_bus_acquired(GDBusConnection *conn, hostname1_set_kernel_release(hostnamed_interf, our_get_kernel_release()); hostname1_set_operating_system_cpename(hostnamed_interf, our_get_os_cpename()); hostname1_set_operating_system_pretty_name(hostnamed_interf, our_get_os_pretty_name()); + hostname1_set_deployment(hostnamed_interf, our_get_deployment()); + hostname1_set_location(hostnamed_interf, our_get_location()); + if(!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(hostnamed_interf), conn, @@ -658,7 +798,6 @@ static void hostnamed_on_bus_acquired(GDBusConnection *conn, hostnamed_mem_clean(); } else { - dbus_interface_exported = TRUE; g_printf("exported %s's interface on the system bus...\n", name); } @@ -767,16 +906,20 @@ int main() { gboolean set_names() { /* (1) set up */ - gchar *hostname_buf, *static_hostname_buf, *pretty_hostname_buf; + gchar *hostname_buf, *static_hostname_buf, *pretty_hostname_buf, *location_buf, *deployment_buf; size_t hostname_divider; hostname_buf = (gchar*) g_malloc0(MAXHOSTNAMELEN); static_hostname_buf = (gchar*) g_malloc0(4096); pretty_hostname_buf = (gchar*) g_malloc0(4096); + location_buf = (gchar*) g_malloc0(LOCATION_MAXSIZE); + deployment_buf = (gchar*) g_malloc0(DEPLOYMENT_MAXSIZE); g_ptr_array_add(hostnamed_freeable, hostname_buf); g_ptr_array_add(hostnamed_freeable, static_hostname_buf); g_ptr_array_add(hostnamed_freeable, pretty_hostname_buf); + g_ptr_array_add(hostnamed_freeable, location_buf); + g_ptr_array_add(hostnamed_freeable, deployment_buf); /* (2) set HOSTNAME */ if(gethostname(hostname_buf, MAXHOSTNAMELEN) || !g_strcmp0(hostname_buf, "")) @@ -803,7 +946,13 @@ gboolean set_names() { else STATIC_HOSTNAME = ""; - return (HOSTNAME && STATIC_HOSTNAME && PRETTY_HOSTNAME) ? TRUE : FALSE; + /* XXX */ + location_buf = ""; + LOCATION = location_buf; + deployment_buf = ""; + DEPLOYMENT = deployment_buf; + + return (HOSTNAME && STATIC_HOSTNAME && PRETTY_HOSTNAME && LOCATION && DEPLOYMENT) ? TRUE : FALSE; } gboolean set_uname_properties() { |