tizen 2.4 release
[framework/telephony/tel-plugin-packetservice.git] / src / ps_util.c
1 /*
2  * tel-plugin-packetservice
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: DongHoo Park <donghoo.park@samsung.com>
7  *          Arun Shukla <arun.shukla@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <unistd.h>
24 #include <wait.h>
25 #include <security-server.h>
26
27 #include <libxml/xmlmemory.h>
28 #include <libxml/parser.h>
29 #include <libxml/tree.h>
30
31 #include "ps_common.h"
32
33 gboolean ps_util_check_access_control(GDBusMethodInvocation *invoc,
34         const char *label, const char *perm)
35 {
36         GDBusConnection *conn;
37         GVariant *result_pid;
38         GVariant *param;
39         GError *error = NULL;
40         const char *sender;
41         unsigned int pid;
42         int ret;
43         int result = FALSE;
44
45         conn = g_dbus_method_invocation_get_connection(invoc);
46         if (!conn) {
47                 warn("access control denied (no connection info)");
48                 goto OUT;
49         }
50
51         sender = g_dbus_method_invocation_get_sender(invoc);
52
53         param = g_variant_new("(s)", sender);
54         if (!param) {
55                 warn("access control denied (sender info fail)");
56                 goto OUT;
57         }
58
59         result_pid = g_dbus_connection_call_sync(conn, "org.freedesktop.DBus",
60                         "/org/freedesktop/DBus",
61                         "org.freedesktop.DBus",
62                         "GetConnectionUnixProcessID",
63                         param, NULL,
64                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
65         if (error) {
66                 warn("access control denied (dbus error: %d(%s))",
67                                 error->code, error->message);
68                 g_error_free(error);
69                 goto OUT;
70         }
71
72         if (!result_pid) {
73                 warn("access control denied (fail to get pid)");
74                 goto OUT;
75         }
76
77         g_variant_get(result_pid, "(u)", &pid);
78         g_variant_unref(result_pid);
79
80         dbg("sender: %s pid = %u", sender, pid);
81
82         /*
83          * Check for permissions
84          */
85         ret = security_server_check_privilege_by_pid(pid, label, perm);
86         if (ret != SECURITY_SERVER_API_SUCCESS)
87                 warn("pid(%u) access (%s - %s) denied(%d)", pid, label, perm, ret);
88         else
89                 result = TRUE;
90
91 OUT:
92         if (result == FALSE)
93                 g_dbus_method_invocation_return_error(invoc,
94                         G_DBUS_ERROR,
95                         G_DBUS_ERROR_ACCESS_DENIED,
96                         "No access rights");
97
98         return result;
99 }
100
101 GSource *ps_util_gsource_dispatch(GMainContext *main_context,
102         gint priority, GSourceFunc cb, gpointer data)
103 {
104         GSource *request_source = NULL;
105
106         request_source = g_idle_source_new();
107         g_source_set_callback(request_source, cb, data, NULL);
108         g_source_set_priority(request_source, priority);
109         g_source_attach(request_source, main_context);
110
111         return request_source;
112 }
113
114 gboolean ps_util_thread_dispatch(GMainContext *main_context,
115         gint priority, GSourceFunc cb, gpointer data)
116 {
117
118         GSource *request_source;
119
120         if (main_context == NULL || cb == NULL) {
121                 err("Failed to dispatch");
122                 return FALSE;
123         }
124
125         /*
126          * Dispatch to source
127          */
128         request_source = ps_util_gsource_dispatch(main_context, priority, cb, data);
129         g_source_unref(request_source);
130
131         return TRUE;
132 }
133
134 int ps_util_system_command(char *command)
135 {
136         int pid = 0,
137         status = 0;
138         const char *environ[] = { NULL };
139
140         if (command == NULL)
141                 return -1;
142
143         dbg("%s", command);
144
145         pid = fork();
146         if (pid == -1)
147                 return -1;
148
149         if (pid == 0) {
150                 char *argv[4];
151
152                 argv[0] = "/bin/sh";
153                 argv[1] = "-c";
154                 argv[2] = (char *)command;
155                 argv[3] = 0;
156
157                 execve("/bin/sh", argv, (char **)environ);
158                 err("execve() failed");
159         }
160
161         do {
162                 if (waitpid(pid, &status, 0) == -1) {
163                         if (errno != EINTR)
164                                 return -1;
165                 } else {
166                         if (WIFEXITED(status))
167                                 return WEXITSTATUS(status);
168                         else if (WIFSIGNALED(status))
169                                 return WTERMSIG(status);
170                         else if (WIFSTOPPED(status))
171                                 return WSTOPSIG(status);
172                 }
173         } while (!WIFEXITED(status) && !WIFSIGNALED(status));
174
175         return 0;
176 }
177
178 void ps_util_load_xml_file(const char *docname,
179         const char *groupname, void **i_doc, void **i_root_node)
180 {
181         xmlDocPtr *doc = (xmlDocPtr *)i_doc;
182         xmlNodePtr *root_node = (xmlNodePtr *)i_root_node;
183
184         dbg("docname: [%s] groupname: [%s]", docname, groupname);
185
186         *doc = xmlParseFile(docname);
187         if (*doc) {
188                 *root_node = xmlDocGetRootElement(*doc);
189                 if (*root_node) {
190                         dbg("*root_node->name: [%s]", (*root_node)->name);
191                         if (0 == xmlStrcmp((*root_node)->name,
192                                         (const unsigned char *)groupname)) {
193                                 dbg("root_node is found !!!");
194                                 return;
195                         } else {
196                                 err("Cannot find root node.");
197                                 *root_node = NULL;
198                         }
199                 }
200
201                 /* Free doc */
202                 xmlFreeDoc(*doc);
203                 *doc = NULL;
204         } else {
205                 err("Failed to parse doc: [%s]", docname);
206         }
207 }
208
209 void ps_util_unload_xml_file(void **i_doc, void **i_root_node)
210 {
211         xmlDocPtr *doc = (xmlDocPtr *)i_doc;
212         xmlNodePtr *root_node = (xmlNodePtr *)i_root_node;
213
214         dbg("unloading XML");
215         if (doc && *doc) {
216                 /* Free doc */
217                 xmlFreeDoc(*doc);
218                 *doc = NULL;
219
220                 if (root_node)
221                         *root_node = NULL;
222         }
223 }