summaryrefslogtreecommitdiff
path: root/libpolkit/libpolkit-grant.c
diff options
context:
space:
mode:
authorDavid Zeuthen <david@fubar.dk>2006-06-05 23:39:00 +0000
committerDavid Zeuthen <david@fubar.dk>2006-06-05 23:39:00 +0000
commit1c3d5691ad444ae2849d079e3745d6b476614623 (patch)
tree0692c2f1eb10b1ea952449d09782cccb826588a6 /libpolkit/libpolkit-grant.c
parent12d20fc8a71b59584f5636ac4dc85c36e45c0157 (diff)
downloadpolkit-1c3d5691ad444ae2849d079e3745d6b476614623.tar.gz
Lots of changes! Almost ready for 0.2 release.
Diffstat (limited to 'libpolkit/libpolkit-grant.c')
-rw-r--r--libpolkit/libpolkit-grant.c407
1 files changed, 407 insertions, 0 deletions
diff --git a/libpolkit/libpolkit-grant.c b/libpolkit/libpolkit-grant.c
new file mode 100644
index 0000000..4e9e7d1
--- /dev/null
+++ b/libpolkit/libpolkit-grant.c
@@ -0,0 +1,407 @@
+/***************************************************************************
+ *
+ * libpolkit-grant.c : Wraps temporary grant methods on the PolicyKit daemon
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * 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 program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib/gstdio.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <libpolkit/libpolkit.h>
+#include "libpolkit-grant.h"
+
+#include "polkit-interface-manager-glue.h"
+#include "polkit-interface-session-glue.h"
+
+struct LibPolKitGrantContext_s
+{
+ DBusGConnection *dbus_g_connection;
+ char *user;
+ char *privilege;
+ char *resource;
+ gboolean restrict_to_dbus_connection;
+
+ LibPolKitGrantQuestions questions_handler;
+ LibPolKitGrantComplete grant_complete_handler;
+
+ char *auth_user;
+ char *auth_service_name;
+
+ DBusGProxy *manager;
+ DBusGProxy *session;
+
+ LibPolKitContext *polkit_ctx;
+
+ gpointer user_data;
+};
+
+
+static void
+have_questions_handler (DBusGProxy *session, gpointer user_data)
+{
+ char **questions;
+ GError *error = NULL;
+ LibPolKitGrantContext *ctx = (LibPolKitGrantContext *) user_data;
+ gboolean should_continue;
+
+ should_continue = FALSE;
+
+ if (!org_freedesktop_PolicyKit_Session_get_questions (ctx->session,
+ &questions,
+ &error)) {
+ g_warning ("GetQuestions: %s", error->message);
+
+ /* we're done */
+ ctx->grant_complete_handler (ctx, FALSE, error->message, ctx->user_data);
+
+ g_error_free (error);
+
+ } else {
+ ctx->questions_handler (ctx, (const char **) questions, ctx->user_data);
+ g_strfreev (questions);
+ }
+}
+
+void
+libpolkit_grant_provide_answers (LibPolKitGrantContext *ctx, const char **answers)
+{
+ GError *error = NULL;
+
+ if (!org_freedesktop_PolicyKit_Session_provide_answers (ctx->session,
+ (const char **) answers,
+ &error)) {
+ g_warning ("ProvideAnswers: %s", error->message);
+
+ /* we're done */
+ ctx->grant_complete_handler (ctx, FALSE, error->message, ctx->user_data);
+
+ g_error_free (error);
+ }
+}
+
+
+static void
+auth_done_handler (DBusGProxy *session, gpointer user_data)
+{
+ gboolean auth_result;
+ //gboolean was_revoked;
+ GError *error = NULL;
+ LibPolKitGrantContext *ctx = (LibPolKitGrantContext *) user_data;
+
+ /*g_debug ("in %s", __FUNCTION__);*/
+
+ if (!org_freedesktop_PolicyKit_Session_is_authenticated (session,
+ &auth_result,
+ &error)) {
+ g_warning ("IsAuthenticated: %s", error->message);
+
+ /* we're done */
+ ctx->grant_complete_handler (ctx, FALSE, error->message, ctx->user_data);
+
+ g_error_free (error);
+ goto out;
+ }
+
+ /*g_message ("Authentication done. %s", auth_result);*/
+
+ if (!auth_result) {
+ char *auth_denied_reason;
+
+ if (!org_freedesktop_PolicyKit_Session_get_auth_denied_reason (session,
+ &auth_denied_reason,
+ &error)) {
+ g_warning ("GetAuthDeniedReason: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /*g_print ("\n"
+ "Authentication failed (reason: '%s').\n", auth_denied_reason);*/
+
+ /* we're done */
+ ctx->grant_complete_handler (ctx, FALSE, auth_denied_reason, ctx->user_data);
+
+ g_free (auth_denied_reason);
+
+ } else {
+ /*g_print ("\n"
+ "Authentication succeeded.\n");*/
+
+ /* don't restrict privilege to callers unique system bus connection name */
+ if (!org_freedesktop_PolicyKit_Session_grant_privilege_temporarily (session,
+ ctx->restrict_to_dbus_connection,
+ &error)) {
+ g_warning ("GrantPrivilegeTemporarily: %s", error->message);
+
+ /* we're done */
+ ctx->grant_complete_handler (ctx, FALSE, error->message, ctx->user_data);
+
+ g_error_free (error);
+
+
+ } else {
+ /* we're done */
+ ctx->grant_complete_handler (ctx, TRUE, NULL, ctx->user_data);
+
+ }
+
+ }
+
+
+ //sleep (20);
+
+ //libpolkit_revoke_temporary_privilege (ctx, grant_user, grant_privilege, grant_resource, &was_revoked);
+ //g_debug ("was revoked = %d", was_revoked);
+ //sleep (10000);
+
+out:
+ ;
+}
+
+
+/**
+ * libpolkit_grant_new_context:
+ * @user: User to request privilege for
+ * @privilege: Privilege to ask for
+ * @resource: Resource to ask for. May be NULL.
+ * @restrict_to_dbus_connection: Whether the privilege should be restricted to a particular D-BUS connection on the
+ * system message bus.
+ * @user_data: User data to be passed to callbacks
+ *
+ * Create a new context for obtaining a privilege.
+ *
+ * Returns: The context. It is an opaque data structure. Free with libpolkit_grant_free_context.
+ */
+
+LibPolKitGrantContext*
+libpolkit_grant_new_context (DBusGConnection *dbus_g_connection,
+ const char *user,
+ const char *privilege,
+ const char *resource,
+ gboolean restrict_to_dbus_connection,
+ gpointer user_data)
+{
+ LibPolKitGrantContext* ctx;
+
+ ctx = g_new (LibPolKitGrantContext, 1);
+ ctx->dbus_g_connection = dbus_g_connection;
+ ctx->user = g_strdup (user);
+ ctx->privilege = g_strdup (privilege);
+ ctx->resource = g_strdup (resource);
+ ctx->restrict_to_dbus_connection = restrict_to_dbus_connection;
+ ctx->questions_handler = NULL;
+ ctx->grant_complete_handler = NULL;
+ ctx->user_data = user_data;
+
+ ctx->auth_user = NULL;
+ ctx->auth_service_name = NULL;
+
+ ctx->polkit_ctx = libpolkit_new_context (dbus_g_connection_get_connection (dbus_g_connection));
+
+ return ctx;
+}
+
+LibPolKitContext*
+libpolkit_grant_get_libpolkit_context (LibPolKitGrantContext *ctx)
+{
+ return ctx->polkit_ctx;
+}
+
+void
+libpolkit_grant_set_questions_handler (LibPolKitGrantContext *ctx,
+ LibPolKitGrantQuestions questions_handler)
+{
+ ctx->questions_handler = questions_handler;
+}
+
+void
+libpolkit_grant_set_grant_complete_handler (LibPolKitGrantContext *ctx,
+ LibPolKitGrantComplete grant_complete_handler)
+{
+ ctx->grant_complete_handler = grant_complete_handler;
+}
+
+gboolean
+libpolkit_grant_initiate_temporary_grant (LibPolKitGrantContext *ctx)
+{
+ GError *error = NULL;
+ char *session_objpath;
+ gboolean rc;
+
+ rc = FALSE;
+ if (ctx->questions_handler == NULL ||
+ ctx->grant_complete_handler == NULL)
+ goto out;
+
+ ctx->manager = dbus_g_proxy_new_for_name (ctx->dbus_g_connection,
+ "org.freedesktop.PolicyKit",
+ "/org/freedesktop/PolicyKit/Manager",
+ "org.freedesktop.PolicyKit.Manager");
+ if (ctx->manager == NULL)
+ goto out;
+
+ if (!org_freedesktop_PolicyKit_Manager_initiate_temporary_privilege_grant (ctx->manager,
+ ctx->user,
+ ctx->privilege,
+ ctx->resource,
+ &session_objpath,
+ &error)) {
+ g_warning ("GrantPrivilege: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /*g_debug ("session_objpath = %s", session_objpath);*/
+
+ ctx->session = dbus_g_proxy_new_for_name (ctx->dbus_g_connection,
+ "org.freedesktop.PolicyKit",
+ session_objpath,
+ "org.freedesktop.PolicyKit.Session");
+ if (ctx->session == NULL)
+ goto out;
+
+ dbus_g_proxy_add_signal (ctx->session, "HaveQuestions", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (ctx->session, "HaveQuestions", G_CALLBACK (have_questions_handler),
+ (void *) ctx, NULL);
+
+ dbus_g_proxy_add_signal (ctx->session, "AuthenticationDone", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (ctx->session, "AuthenticationDone", G_CALLBACK (auth_done_handler),
+ (void *) ctx, NULL);
+
+ if (!org_freedesktop_PolicyKit_Session_get_auth_details (ctx->session,
+ &ctx->auth_user,
+ &ctx->auth_service_name,
+ &error)) {
+ g_warning ("GetAuthDetails: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ if (!org_freedesktop_PolicyKit_Session_initiate_auth (ctx->session,
+ &error)) {
+ g_warning ("InitiateAuth: %s", error->message);
+ g_error_free (error);
+ /* TODO: LIBPOLKIT_GRANT_RESULT_NO_SUCH_PRIVILEGE, LIBPOLKIT_GRANT_RESULT_CANNOT_AUTH_FOR_PRIVILEGE */
+ goto out;
+ }
+
+
+ g_free (session_objpath);
+
+ rc = TRUE;
+out:
+
+ return rc;
+}
+
+
+const char*
+libpolkit_grant_get_user_for_auth (LibPolKitGrantContext *ctx)
+{
+ return ctx->auth_user;
+}
+
+const char*
+libpolkit_grant_get_pam_service_for_auth (LibPolKitGrantContext *ctx)
+{
+ return ctx->auth_service_name;
+}
+
+gboolean
+libpolkit_grant_close (LibPolKitGrantContext *ctx,
+ gboolean revoke_privilege)
+{
+ GError *error = NULL;
+
+ /* got the privilege; now close the session.. */
+ if (!org_freedesktop_PolicyKit_Session_close (ctx->session,
+ &error)) {
+ g_warning ("Close: %s", error->message);
+ g_error_free (error);
+ }
+
+ if (revoke_privilege) {
+ gboolean was_revoked;
+
+ libpolkit_revoke_temporary_privilege (ctx->polkit_ctx,
+ ctx->user,
+ ctx->privilege,
+ ctx->resource,
+ &was_revoked);
+
+ if (!was_revoked) {
+ g_warning ("Couldn't revoke privilege");
+ }
+
+ }
+
+ return TRUE;
+}
+
+void
+libpolkit_grant_free_context (LibPolKitGrantContext *ctx)
+{
+ g_free (ctx->user);
+ g_free (ctx->privilege);
+ g_free (ctx->resource);
+ g_free (ctx->auth_user);
+ g_free (ctx->auth_service_name);
+ libpolkit_free_context (ctx->polkit_ctx);
+ g_free (ctx);
+}
+
+const char*
+libpolkit_grant_get_user (LibPolKitGrantContext *ctx)
+{
+ return ctx->user;
+}
+
+const char*
+libpolkit_grant_get_privilege (LibPolKitGrantContext *ctx)
+{
+ return ctx->privilege;
+}
+
+/**
+ * libpolkit_grant_get_resource:
+ * @ctx: Context
+ *
+ * Get the resource as passed in from libpolkit_grant_new_context.
+ *
+ * Returns: The resource. May be NULL.
+ */
+const char*
+libpolkit_grant_get_resource (LibPolKitGrantContext *ctx)
+{
+ return ctx->resource;
+}
+