~xavi-garcia-mena/ubuntu/vivid/upower/percentages-power-off

« back to all changes in this revision

Viewing changes to src/up-polkit.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2010-02-16 10:16:24 UTC
  • Revision ID: james.westby@ubuntu.com-20100216101624-2cmwqsr1ndftdd87
Tags: upstream-0.9.0+git20100216.72bb2
ImportĀ upstreamĀ versionĀ 0.9.0+git20100216.72bb2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
 
4
 * Copyright (C) 2008 Richard Hughes <richard@hughsie.com>
 
5
 *
 
6
 * Licensed under the GNU General Public License Version 2
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; if not, write to the Free Software
 
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
21
 */
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
#  include <config.h>
 
25
#endif
 
26
 
 
27
#include <glib.h>
 
28
#include <dbus/dbus-glib.h>
 
29
#include <dbus/dbus-glib-lowlevel.h>
 
30
 
 
31
#include <polkit/polkit.h>
 
32
 
 
33
#include "egg-debug.h"
 
34
 
 
35
#include "up-polkit.h"
 
36
#include "up-daemon.h"
 
37
 
 
38
#define UP_POLKIT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UP_TYPE_POLKIT, UpPolkitPrivate))
 
39
 
 
40
struct UpPolkitPrivate
 
41
{
 
42
        DBusGConnection         *connection;
 
43
        PolkitAuthority         *authority;
 
44
};
 
45
 
 
46
G_DEFINE_TYPE (UpPolkit, up_polkit, G_TYPE_OBJECT)
 
47
static gpointer up_polkit_object = NULL;
 
48
 
 
49
/**
 
50
 * up_polkit_get_subject:
 
51
 **/
 
52
PolkitSubject *
 
53
up_polkit_get_subject (UpPolkit *polkit, DBusGMethodInvocation *context)
 
54
{
 
55
        const gchar *sender;
 
56
        PolkitSubject *subject;
 
57
 
 
58
        sender = dbus_g_method_get_sender (context);
 
59
        subject = polkit_system_bus_name_new (sender);
 
60
 
 
61
        return subject;
 
62
}
 
63
 
 
64
/**
 
65
 * up_polkit_check_auth:
 
66
 **/
 
67
gboolean
 
68
up_polkit_check_auth (UpPolkit *polkit, PolkitSubject *subject, const gchar *action_id, DBusGMethodInvocation *context)
 
69
{
 
70
        gboolean ret = FALSE;
 
71
        GError *error;
 
72
        GError *error_local;
 
73
        PolkitAuthorizationResult *result;
 
74
 
 
75
        /* check auth */
 
76
        result = polkit_authority_check_authorization_sync (polkit->priv->authority, subject, action_id, NULL, POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, NULL, &error_local);
 
77
        if (result == NULL) {
 
78
                error = g_error_new (UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL, "failed to check authorisation: %s", error_local->message);
 
79
                dbus_g_method_return_error (context, error);
 
80
                g_error_free (error_local);
 
81
                g_error_free (error);
 
82
                goto out;
 
83
        }
 
84
 
 
85
        /* okay? */
 
86
        if (polkit_authorization_result_get_is_authorized (result)) {
 
87
                ret = TRUE;
 
88
        } else {
 
89
                error = g_error_new (UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL, "not authorized");
 
90
                dbus_g_method_return_error (context, error);
 
91
                g_error_free (error);
 
92
        }
 
93
out:
 
94
        if (result != NULL)
 
95
                g_object_unref (result);
 
96
        return ret;
 
97
}
 
98
 
 
99
/**
 
100
 * up_polkit_is_allowed:
 
101
 **/
 
102
gboolean
 
103
up_polkit_is_allowed (UpPolkit *polkit, PolkitSubject *subject, const gchar *action_id, DBusGMethodInvocation *context)
 
104
{
 
105
        gboolean ret = FALSE;
 
106
        GError *error;
 
107
        GError *error_local;
 
108
        PolkitAuthorizationResult *result;
 
109
 
 
110
        /* check auth */
 
111
        result = polkit_authority_check_authorization_sync (polkit->priv->authority, subject, action_id, NULL, POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE, NULL, &error_local);
 
112
        if (result == NULL) {
 
113
                error = g_error_new (UP_DAEMON_ERROR, UP_DAEMON_ERROR_GENERAL, "failed to check authorisation: %s", error_local->message);
 
114
                dbus_g_method_return_error (context, error);
 
115
                g_error_free (error_local);
 
116
                g_error_free (error);
 
117
                goto out;
 
118
        }
 
119
 
 
120
        ret = polkit_authorization_result_get_is_authorized (result) ||
 
121
              polkit_authorization_result_get_is_challenge (result);
 
122
out:
 
123
        if (result != NULL)
 
124
                g_object_unref (result);
 
125
        return ret;
 
126
}
 
127
 
 
128
/**
 
129
 * up_polkit_get_uid:
 
130
 **/
 
131
gboolean
 
132
up_polkit_get_uid (UpPolkit *polkit, PolkitSubject *subject, uid_t *uid)
 
133
{
 
134
        DBusConnection *connection;
 
135
        const gchar *name;
 
136
 
 
137
        if (!POLKIT_IS_SYSTEM_BUS_NAME (subject)) {
 
138
                egg_debug ("not system bus name");
 
139
                return FALSE;
 
140
        }
 
141
 
 
142
        connection = dbus_g_connection_get_connection (polkit->priv->connection);
 
143
        name = polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject));
 
144
        *uid = dbus_bus_get_unix_user (connection, name, NULL);
 
145
        return TRUE;
 
146
}
 
147
 
 
148
/**
 
149
 * up_polkit_get_pid:
 
150
 **/
 
151
gboolean
 
152
up_polkit_get_pid (UpPolkit *polkit, PolkitSubject *subject, pid_t *pid)
 
153
{
 
154
        gboolean ret = FALSE;
 
155
        GError *error = NULL;
 
156
        const gchar *name;
 
157
        DBusGProxy *proxy = NULL;
 
158
 
 
159
        /* bus name? */
 
160
        if (!POLKIT_IS_SYSTEM_BUS_NAME (subject)) {
 
161
                egg_debug ("not system bus name");
 
162
                goto out;
 
163
        }
 
164
 
 
165
        name = polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject));
 
166
        proxy = dbus_g_proxy_new_for_name_owner (polkit->priv->connection,
 
167
                                                 "org.freedesktop.DBus",
 
168
                                                 "/org/freedesktop/DBus/Bus",
 
169
                                                 "org.freedesktop.DBus", &error);
 
170
        if (proxy == NULL) {
 
171
                egg_warning ("DBUS error: %s", error->message);
 
172
                g_error_free (error);
 
173
                goto out;
 
174
        }
 
175
 
 
176
        /* get pid from DBus (quite slow) */
 
177
        ret = dbus_g_proxy_call (proxy, "GetConnectionUnixProcessID", &error,
 
178
                                 G_TYPE_STRING, name,
 
179
                                 G_TYPE_INVALID,
 
180
                                 G_TYPE_UINT, pid,
 
181
                                 G_TYPE_INVALID);
 
182
        if (!ret) {
 
183
                egg_warning ("failed to get pid: %s", error->message);
 
184
                g_error_free (error);
 
185
                goto out;
 
186
        }
 
187
out:
 
188
        if (proxy != NULL)
 
189
                g_object_unref (proxy);
 
190
        return ret;
 
191
}
 
192
 
 
193
/**
 
194
 * up_polkit_finalize:
 
195
 **/
 
196
static void
 
197
up_polkit_finalize (GObject *object)
 
198
{
 
199
        UpPolkit *polkit;
 
200
        g_return_if_fail (UP_IS_POLKIT (object));
 
201
        polkit = UP_POLKIT (object);
 
202
 
 
203
        if (polkit->priv->connection != NULL)
 
204
                dbus_g_connection_unref (polkit->priv->connection);
 
205
        g_object_unref (polkit->priv->authority);
 
206
 
 
207
        G_OBJECT_CLASS (up_polkit_parent_class)->finalize (object);
 
208
}
 
209
 
 
210
/**
 
211
 * up_polkit_class_init:
 
212
 **/
 
213
static void
 
214
up_polkit_class_init (UpPolkitClass *klass)
 
215
{
 
216
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
217
        object_class->finalize = up_polkit_finalize;
 
218
        g_type_class_add_private (klass, sizeof (UpPolkitPrivate));
 
219
}
 
220
 
 
221
/**
 
222
 * up_polkit_init:
 
223
 *
 
224
 * initializes the polkit class. NOTE: We expect polkit objects
 
225
 * to *NOT* be removed or added during the session.
 
226
 * We only control the first polkit object if there are more than one.
 
227
 **/
 
228
static void
 
229
up_polkit_init (UpPolkit *polkit)
 
230
{
 
231
        GError *error = NULL;
 
232
 
 
233
        polkit->priv = UP_POLKIT_GET_PRIVATE (polkit);
 
234
 
 
235
        polkit->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
 
236
        if (polkit->priv->connection == NULL) {
 
237
                if (error != NULL) {
 
238
                        g_critical ("error getting system bus: %s", error->message);
 
239
                        g_error_free (error);
 
240
                }
 
241
                goto out;
 
242
        }
 
243
        polkit->priv->authority = polkit_authority_get ();
 
244
out:
 
245
        return;
 
246
}
 
247
 
 
248
/**
 
249
 * up_polkit_new:
 
250
 * Return value: A new polkit class instance.
 
251
 **/
 
252
UpPolkit *
 
253
up_polkit_new (void)
 
254
{
 
255
        if (up_polkit_object != NULL) {
 
256
                g_object_ref (up_polkit_object);
 
257
        } else {
 
258
                up_polkit_object = g_object_new (UP_TYPE_POLKIT, NULL);
 
259
                g_object_add_weak_pointer (up_polkit_object, &up_polkit_object);
 
260
        }
 
261
        return UP_POLKIT (up_polkit_object);
 
262
}
 
263
 
 
264
/***************************************************************************
 
265
 ***                          MAKE CHECK TESTS                           ***
 
266
 ***************************************************************************/
 
267
#ifdef EGG_TEST
 
268
#include "egg-test.h"
 
269
 
 
270
void
 
271
up_polkit_test (gpointer user_data)
 
272
{
 
273
        EggTest *test = (EggTest *) user_data;
 
274
        UpPolkit *polkit;
 
275
 
 
276
        if (!egg_test_start (test, "UpPolkit"))
 
277
                return;
 
278
 
 
279
        /************************************************************/
 
280
        egg_test_title (test, "get instance");
 
281
        polkit = up_polkit_new ();
 
282
        egg_test_assert (test, polkit != NULL);
 
283
 
 
284
        /* unref */
 
285
        g_object_unref (polkit);
 
286
 
 
287
        egg_test_end (test);
 
288
}
 
289
#endif
 
290