Update copyright information
[connman] / plugins / polkit.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <errno.h>
27
28 #include <glib.h>
29 #include <polkit-dbus/polkit-dbus.h>
30
31 #define CONNMAN_API_SUBJECT_TO_CHANGE
32 #include <connman/plugin.h>
33 #include <connman/security.h>
34 #include <connman/dbus.h>
35 #include <connman/log.h>
36
37 #define ACTION "org.moblin.connman.modify"
38
39 static DBusConnection *connection;
40 static PolKitContext *polkit_context;
41
42 static int polkit_authorize(const char *sender)
43 {
44         DBusError error;
45         PolKitCaller *caller;
46         PolKitAction *action;
47         PolKitResult result;
48
49         DBG("sender %s", sender);
50
51         dbus_error_init(&error);
52
53         caller = polkit_caller_new_from_dbus_name(connection, sender, &error);
54         if (caller == NULL) {
55                 if (dbus_error_is_set(&error) == TRUE) {
56                         connman_error("%s", error.message);
57                         dbus_error_free(&error);
58                 } else
59                         connman_error("Failed to get caller information");
60                 return -EIO;
61         }
62
63         action = polkit_action_new();
64         polkit_action_set_action_id(action, ACTION);
65
66         result = polkit_context_is_caller_authorized(polkit_context,
67                                                 action, caller, TRUE, NULL);
68
69         polkit_action_unref(action);
70         polkit_caller_unref(caller);
71
72         DBG("result %s", polkit_result_to_string_representation(result));
73
74         if (result == POLKIT_RESULT_NO)
75                 return -EPERM;
76
77         return 0;
78 }
79
80 static struct connman_security polkit_security = {
81         .name                   = "polkit",
82         .authorize_sender       = polkit_authorize,
83 };
84
85 static gboolean watch_event(GIOChannel *channel, GIOCondition condition,
86                                                         gpointer user_data)
87 {
88         PolKitContext *context = user_data;
89         int fd;
90
91         DBG("context %p", context);
92
93         fd = g_io_channel_unix_get_fd(channel);
94
95         polkit_context_io_func(context, fd);
96
97         return TRUE;
98 }
99
100 static int add_watch(PolKitContext *context, int fd)
101 {
102         GIOChannel *channel;
103         guint id = 0;
104
105         DBG("context %p", context);
106
107         channel = g_io_channel_unix_new(fd);
108         if (channel == NULL)
109                 return 0;
110
111         id = g_io_add_watch(channel, G_IO_IN, watch_event, context);
112
113         g_io_channel_unref(channel);
114
115         return id;
116 }
117
118 static void remove_watch(PolKitContext *context, int id)
119 {
120         DBG("context %p", context);
121
122         g_source_remove(id);
123 }
124
125 static int polkit_init(void)
126 {
127         int err;
128
129         connection = connman_dbus_get_connection();
130         if (connection == NULL)
131                 return -EIO;
132
133         polkit_context = polkit_context_new();
134
135         polkit_context_set_io_watch_functions(polkit_context,
136                                                 add_watch, remove_watch);
137
138         if (polkit_context_init(polkit_context, NULL) == FALSE) {
139                 connman_error("Can't initialize PolicyKit");
140                 polkit_context_unref(polkit_context);
141                 dbus_connection_unref(connection);
142                 return -EIO;
143         }
144
145         err = connman_security_register(&polkit_security);
146         if (err < 0) {
147                 polkit_context_unref(polkit_context);
148                 dbus_connection_unref(connection);
149                 return err;
150         }
151
152         return 0;
153 }
154
155 static void polkit_exit(void)
156 {
157         connman_security_unregister(&polkit_security);
158
159         polkit_context_unref(polkit_context);
160
161         dbus_connection_unref(connection);
162 }
163
164 CONNMAN_PLUGIN_DEFINE(polkit, "PolicyKit authorization plugin", VERSION,
165                                                 polkit_init, polkit_exit)