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