summaryrefslogtreecommitdiffstats
path: root/sfshare-daemon/dbus_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'sfshare-daemon/dbus_service.c')
-rwxr-xr-xsfshare-daemon/dbus_service.c459
1 files changed, 459 insertions, 0 deletions
diff --git a/sfshare-daemon/dbus_service.c b/sfshare-daemon/dbus_service.c
new file mode 100755
index 0000000..3e08c6d
--- /dev/null
+++ b/sfshare-daemon/dbus_service.c
@@ -0,0 +1,459 @@
+/*
+ * dbus_service.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Jan Lipovsky <janlipovsky@gmail.com>
+ */
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <glib-object.h>
+
+#include <polkit/polkit.h>
+
+#include "samba_share.h"
+#include "dbus_service.h"
+#include "sfshare_errors.h"
+
+/* DBUS metods */
+#define ACTION_ID_SETUP_SHARE "org.fedoraproject.SimpleFileShare.setup_share"
+#define ASTION_ID_GET_SHARE_STATUS "org.fedoraproject.SimpleFileShare.get_share_status"
+#define ASTION_ID_DELETE_SHARE "org.fedoraproject.SimpleFileShare.delete_share"
+
+
+typedef struct DaemonObject DaemonObject;
+typedef struct DaemonObjectClass DaemonObjectClass;
+
+static PolkitSubject *subject_dbus = NULL;
+static PolkitAuthority *authority = NULL;
+
+
+gboolean is_authorized = FALSE;
+DBusGConnection *bus;
+DBusGProxy *bus_proxy;
+
+GType daemon_object_get_type (void);
+
+struct DaemonObject
+{
+ GObject parent;
+};
+
+struct DaemonObjectClass
+{
+ GObjectClass parent;
+};
+
+
+#define DAEMON_TYPE_OBJECT (daemon_object_get_type ())
+#define DAEMON_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), DAEMON_TYPE_OBJECT, DaemonObject))
+#define DAEMON_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DAEMON_TYPE_OBJECT, DaemonObjectClass))
+#define DAEMON_IS_OBJECT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), DAEMON_TYPE_OBJECT))
+#define DAEMON_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DAEMON_TYPE_OBJECT))
+#define DAEMON_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DAEMON_TYPE_OBJECT, DaemonObjectClass))
+
+G_DEFINE_TYPE(DaemonObject, daemon_object, G_TYPE_OBJECT)
+
+gboolean daemon_get_share_status (DaemonObject *obj, const gchar *path, gchar ***result, GError **error);
+
+/* Async calls */
+gboolean daemon_setup_share (DaemonObject *obj, const gchar **parameters, DBusGMethodInvocation *context);
+gboolean daemon_delete_share (DaemonObject *obj,const gchar *path, DBusGMethodInvocation *context);
+
+#include "dbus_service_glue.h"
+
+/**
+* Return text of Error
+*/
+gchar *
+get_error_msg (Error_sfshare err)
+{
+ gchar *errmsg;
+
+ switch (err)
+ {
+ case ERROR_FAILED:
+ errmsg = g_strdup ("Failed");
+ break;
+
+ case ERROR_PERMISSION_DENIED:
+ errmsg = g_strdup ("Permission denied");
+ break;
+
+ case ERROR_FILE_NOT_EXIST:
+ errmsg = g_strdup ("Config file does not exist");
+ break;
+
+ case ERROR_CAN_NOT_OPEN_FILE:
+ errmsg = g_strdup ("Can not open config file");
+ break;
+
+ case ERROR_DIRECTORY_NOT_SHARED:
+ errmsg = g_strdup ("Directory is not shared");
+ break;
+
+ case ERROR_WRONG_NAME:
+ errmsg = g_strdup ("Wrong name");
+ break;
+
+ case ERROR_WRONG_PATH:
+ errmsg = g_strdup ("Wrong path");
+ break;
+
+ case ERROR_READONLY_WRITABLE:
+ errmsg = g_strdup ("Read only is same as writable");
+ break;
+
+ case ERROR_SHARE_NAME_EXIST:
+ errmsg = g_strdup ("Share name already exist");
+ break;
+
+ default:
+ errmsg = g_strdup ("Unknow error type");
+ break;
+ }
+
+ return errmsg;
+}
+
+
+GQuark
+get_error_quark (void)
+{
+ static GQuark ret = 0;
+
+ if (ret == 0)
+ {
+ ret = g_quark_from_static_string ("sfshare_daemon_error");
+ }
+ return ret;
+}
+
+
+/** Return error to context */
+static void
+send_error (DBusGMethodInvocation *context,
+ gint error_code,
+ const gchar *format,
+ ...)
+{
+ GError *error;
+ va_list args;
+ gchar *message;
+
+ va_start (args, format);
+ message = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ error = g_error_new (ERROR_QUARK, error_code, "%s", message);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+
+ g_free (message);
+}
+
+
+/**
+* Create pointer to DaemonData filled with values from parameters
+*/
+DaemonData *
+daemon_data_new ( DBusGMethodInvocation *context, AuthorizedCallback auth_cb, const gchar **in)
+{
+ DaemonData *ret;
+
+ ret = g_new0 (DaemonData, 1);
+
+ ret->context = context;
+ ret->authorized_cb = auth_cb;
+
+ ret->in = g_new0 (gchar *, 6);
+
+ gint i = 0;
+
+ while(in[i] != NULL)
+ {
+ ret->in[i] = g_strdup (in[i]);
+ i++;
+ }
+
+ return ret;
+}
+
+/**
+* Free DaemonData pointer
+*/
+void
+daemon_data_free (DaemonData * data)
+{
+ gint i;
+ i = 0;
+
+ while (data->in[i] != NULL)
+ {
+ g_free (data->in[i++]);
+ }
+
+ g_free (data);
+
+}
+
+
+/**
+* PolicyKit callback function
+*/
+static void
+check_authorization_cb (PolkitAuthority *authority,
+ GAsyncResult *res,
+ DaemonData *data)
+{
+ GError *error;
+ PolkitAuthorizationResult *result;
+
+
+ is_authorized = FALSE;
+
+ error = NULL;
+ result = polkit_authority_check_authorization_finish (authority, res, &error);
+ if (error != NULL)
+ {
+ send_error (data->context, ERROR_PERMISSION_DENIED, "Not authorized: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ if (polkit_authorization_result_get_is_authorized (result))
+ {
+ is_authorized = TRUE;
+ }
+ else if (polkit_authorization_result_get_is_challenge (result))
+ {
+ send_error (data->context, ERROR_PERMISSION_DENIED, "Authentication is required");
+ }
+ else
+ {
+ send_error (data->context, ERROR_PERMISSION_DENIED, "Not authorized");
+ }
+ }
+
+ if(is_authorized)
+ {
+ /* Run authorized callback */
+ (* data->authorized_cb) (data);
+ }
+
+ daemon_data_free (data);
+}
+
+
+
+
+
+
+static void
+daemon_object_init (DaemonObject *obj)
+{
+}
+
+static void
+daemon_object_class_init (DaemonObjectClass *klass)
+{
+}
+
+/**
+* Handle incomming request - D-Bus get_share_status
+*/
+gboolean
+daemon_get_share_status (DaemonObject *obj, const gchar *path, gchar ***result, GError **error)
+{
+ /* puts("daemon_get_share_status"); */
+
+ Error_sfshare err;
+
+ err = smb_get_share_status (path, result);
+
+ if (err != OK)
+ {
+ *error = g_error_new (ERROR_QUARK, err, "%s", get_error_msg(err));
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+/**
+* Authorized call of smb_set_share - write or change share section
+*/
+void
+setup_share_authorized (gpointer data)
+{
+ Error_sfshare err;
+ DaemonData *dd = data;
+
+ err = smb_set_share (dd->in);
+
+ if (err != OK)
+ {
+ send_error (dd->context, err, "%s", get_error_msg(err));
+ }
+
+ smb_reload_service ();
+
+ /* Return */
+ dbus_g_method_return (dd->context);
+}
+
+
+
+/**
+* Dbus setup share - polkit authorization check
+*/
+gboolean
+daemon_setup_share (DaemonObject *obj,const gchar **parameters, DBusGMethodInvocation *context)
+{
+ /* puts ("daemon_setup_share"); */
+
+ DaemonData *data;
+ data = daemon_data_new (context, setup_share_authorized, parameters);
+
+ subject_dbus = polkit_system_bus_name_new (dbus_g_method_get_sender (context));
+
+ polkit_authority_check_authorization (authority,
+ subject_dbus,
+ ACTION_ID_SETUP_SHARE,
+ NULL, /* PolkitDetails */
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
+ NULL,
+ (GAsyncReadyCallback) check_authorization_cb,
+ data);
+ return TRUE;
+}
+
+
+
+/**
+* Authorized call of smb_delete_share - delete share section
+*/
+void
+delete_share_authorized (gpointer data)
+{
+ Error_sfshare err;
+ DaemonData *dd = data;
+
+ err = smb_delete_share(dd->in);
+
+ if (err != OK)
+ {
+ send_error (dd->context, err, "%s", get_error_msg(err));
+ }
+
+ smb_reload_service ();
+
+ /* Return */
+ dbus_g_method_return (dd->context);
+}
+
+
+/**
+* Dbus delete share - polkit authorization check
+*/
+gboolean
+daemon_delete_share (DaemonObject *obj, const gchar *path, DBusGMethodInvocation *context)
+{
+ /* puts("daemon_delete_share"); */
+
+ DaemonData *data;
+
+ const gchar *in[2] = {path, NULL};
+
+ data = daemon_data_new (context, delete_share_authorized, in);
+
+ subject_dbus = polkit_system_bus_name_new (dbus_g_method_get_sender (context));
+
+ polkit_authority_check_authorization (authority,
+ subject_dbus,
+ ASTION_ID_DELETE_SHARE,
+ NULL, /* PolkitDetails */
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
+ NULL,
+ (GAsyncReadyCallback) check_authorization_cb,
+ data);
+
+ return TRUE;
+}
+
+
+/**
+* Start of sfshare deamon
+*/
+int
+dbus_sfshare_start ()
+{
+ GError *error = NULL;
+ GMainLoop *mainloop;
+ guint request_name_result;
+ DaemonObject *obj;
+
+ g_type_init ();
+
+ dbus_g_object_type_install_info (DAEMON_TYPE_OBJECT, &dbus_glib_daemon_object_info);
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+
+ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (!bus)
+ {
+ g_warning ("Couldn't connect to system bus : %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+
+ /* PolKit */
+ authority = polkit_authority_get ();
+
+ bus_proxy = dbus_g_proxy_new_for_name (bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+
+ if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error,
+ G_TYPE_STRING, "org.fedoraproject.SimpleFileShare",
+ G_TYPE_UINT, 0,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &request_name_result,
+ G_TYPE_INVALID))
+ {
+ g_warning("Failed to acquire org.fedoraproject.SimpleFileShare : %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+
+ obj = g_object_new (DAEMON_TYPE_OBJECT, NULL);
+
+ dbus_g_connection_register_g_object (bus, "/org/fedoraproject/SimpleFileShare", G_OBJECT (obj));
+
+ g_print ("Simple File Share - service running\n");
+
+ g_main_loop_run (mainloop);
+
+ g_object_unref (obj);
+
+
+ return 0;
+}