Add authorization callback for privileges check
[platform/upstream/connman.git] / plugins / polkit.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2008  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 #include <connman/plugin.h>
32 #include <connman/security.h>
33 #include <connman/log.h>
34
35 #define ACTION "org.moblin.connman.modify"
36
37 static DBusConnection *connection;
38 static PolKitContext *polkit_context;
39
40 static int polkit_authorize(const char *sender)
41 {
42         DBusError error;
43         PolKitCaller *caller;
44         PolKitAction *action;
45         PolKitResult result;
46
47         DBG("sender %s", sender);
48
49         dbus_error_init(&error);
50
51         caller = polkit_caller_new_from_dbus_name(connection, sender, &error);
52         if (caller == NULL) {
53                 if (dbus_error_is_set(&error) == TRUE) {
54                         connman_error("%s", error.message);
55                         dbus_error_free(&error);
56                 } else
57                         connman_error("Failed to get caller information");
58                 return -EIO;
59         }
60
61         action = polkit_action_new();
62         polkit_action_set_action_id(action, ACTION);
63
64         result = polkit_context_is_caller_authorized(polkit_context,
65                                                 action, caller, TRUE, NULL);
66
67         polkit_action_unref(action);
68         polkit_caller_unref(caller);
69
70         DBG("result %s", polkit_result_to_string_representation(result));
71
72         if (result == POLKIT_RESULT_NO)
73                 return -EPERM;
74
75         return 0;
76 }
77
78 static struct connman_security polkit_security = {
79         .name                   = "polkit",
80         .authorize_sender       = polkit_authorize,
81 };
82
83 static gboolean watch_event(GIOChannel *channel, GIOCondition condition,
84                                                         gpointer user_data)
85 {
86         PolKitContext *context = user_data;
87         int fd;
88
89         DBG("context %p", context);
90
91         fd = g_io_channel_unix_get_fd(channel);
92
93         polkit_context_io_func(context, fd);
94
95         return TRUE;
96 }
97
98 static int add_watch(PolKitContext *context, int fd)
99 {
100         GIOChannel *channel;
101         guint id = 0;
102
103         DBG("context %p", context);
104
105         channel = g_io_channel_unix_new(fd);
106         if (channel == NULL)
107                 return 0;
108
109         id = g_io_add_watch(channel, G_IO_IN, watch_event, context);
110
111         g_io_channel_unref(channel);
112
113         return id;
114 }
115
116 static void remove_watch(PolKitContext *context, int id)
117 {
118         DBG("context %p", context);
119
120         g_source_remove(id);
121 }
122
123 static int polkit_init(void)
124 {
125         int err;
126
127         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
128         if (connection == NULL)
129                 return -EIO;
130
131         polkit_context = polkit_context_new();
132
133         polkit_context_set_io_watch_functions(polkit_context,
134                                                 add_watch, remove_watch);
135
136         if (polkit_context_init(polkit_context, NULL) == FALSE) {
137                 connman_error("Can't initialize PolicyKit");
138                 polkit_context_unref(polkit_context);
139                 dbus_connection_unref(connection);
140                 return -EIO;
141         }
142
143         err = connman_security_register(&polkit_security);
144         if (err < 0) {
145                 polkit_context_unref(polkit_context);
146                 dbus_connection_unref(connection);
147                 return err;
148         }
149
150         return 0;
151 }
152
153 static void polkit_exit(void)
154 {
155         connman_security_unregister(&polkit_security);
156
157         polkit_context_unref(polkit_context);
158
159         dbus_connection_unref(connection);
160 }
161
162 CONNMAN_PLUGIN_DEFINE("polkit", "PolicyKit authorization plugin", VERSION,
163                                                 polkit_init, polkit_exit)