From 0c8c4fdd0ab8118100a32fc68e997de0faa4aec9 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Thu, 27 Aug 2015 12:57:15 +0900 Subject: [PATCH] Check privilege via dbus-daemon split dbus method to each request type set privileges to each dbus method Change-Id: Iec515763f0b34baaf0aac8fee1e5098d272df656 Signed-off-by: Sangyoon Jang --- client/CMakeLists.txt | 1 + client/src/pkgmgr.c | 63 +++-- comm/comm_client.h | 6 +- comm/comm_client_gdbus.c | 19 +- comm/pkgmgr-installer-client.pc.in | 2 +- packaging/pkgmgr.spec | 3 - server/CMakeLists.txt | 5 +- server/include/pkgmgr-server.h | 6 + server/include/pm-queue.h | 4 +- server/org.tizen.pkgmgr.conf.in | 11 +- server/src/pkgmgr-server.c | 480 +------------------------------------ server/src/pm-queue.c | 24 +- server/src/request.c | 447 ++++++++++++++++++++++++++++++++++ 13 files changed, 545 insertions(+), 526 deletions(-) create mode 100644 server/src/request.c diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index c7331b0..0b73ac2 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -3,6 +3,7 @@ SET(SRCS src/pkgmgr-internal.c src/pkgmgr.c) pkg_check_modules(CLIENT_DEPS REQUIRED + glib-2.0 dlog pkgmgr-parser pkgmgr-info diff --git a/client/src/pkgmgr.c b/client/src/pkgmgr.c index 05a7200..5fb70ee 100644 --- a/client/src/pkgmgr.c +++ b/client/src/pkgmgr.c @@ -30,6 +30,8 @@ #include #include +#include + #include #include /* For multi-user support */ @@ -757,7 +759,8 @@ static int __get_size_process(pkgmgr_client * pc, const char *pkgid, uid_t uid, DBG("[args] %s [len] %d\n", args, len); /* request */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_GET_SIZE, pkgtype, pkgid, args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "getsize", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, args)); if (ret < 0) ERR("comm_client_request failed, ret=%d\n", ret); @@ -843,7 +846,8 @@ static int __move_pkg_process(pkgmgr_client * pc, const char *pkgid, uid_t uid, DBG("[args] %s [len] %d\n", args, len); /* 6. request */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_TO_MOVER, pkgtype, pkgid, args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "move", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, args)); if (ret < 0) ERR("comm_client_request failed, ret=%d\n", ret); @@ -889,9 +893,11 @@ static int __check_app_process(pkgmgr_request_service_type service_type, pkgmgr_ /* 3. request activate */ if (service_type == PM_REQUEST_KILL_APP) - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_KILL_APP, pkgtype, pkgid, NULL, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "kill", + g_variant_new("(sss)", req_key, pkgtype, pkgid)); else if (service_type == PM_REQUEST_CHECK_APP) - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_CHECK_APP, pkgtype, pkgid, NULL, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "check", + g_variant_new("(sss)", req_key, pkgtype, pkgid)); if (ret < 0) ERR("request failed, ret=%d\n", ret); @@ -957,7 +963,8 @@ static int __request_size_info(pkgmgr_client *pc, uid_t uid) DBG("[args] %s [len] %d\n", args, len); /* request */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_GET_SIZE, pkgtype, pkgid, args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "getsize", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, args)); if (ret < 0) { ERR("COMM_REQ_GET_SIZE failed, ret=%d\n", ret); } @@ -1045,7 +1052,8 @@ static int __get_package_size_info(pkgmgr_client_t *mpc, char *req_key, const ch DBG("[args] %s [len] %d\n", args, len); /* request */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_GET_SIZE, pkgtype, pkgid, args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "getsize", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, args)); if (ret < 0) ERR("COMM_REQ_GET_SIZE failed, ret=%d\n", ret); @@ -1310,7 +1318,8 @@ API int pkgmgr_client_usr_install(pkgmgr_client * pc, const char *pkg_type, /******************* end of quote ************************/ /* 6. request install */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_TO_INSTALLER, pkgtype, pkg_path, args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "install", + g_variant_new("(ssss)", req_key, pkgtype, pkg_path, args)); tryvm_if(ret < 0, ret = PKGMGR_R_ECOMM, "request failed, ret=%d", ret); ret = req_id; @@ -1433,7 +1442,8 @@ API int pkgmgr_client_usr_reinstall(pkgmgr_client * pc, const char *pkg_type, co /******************* end of quote ************************/ /* 6. request install */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_TO_INSTALLER, pkgtype, pkgid, args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "reinstall", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, args)); tryvm_if(ret < 0, ret = PKGMGR_R_ECOMM, "request failed"); ret = req_id; @@ -1561,7 +1571,8 @@ API int pkgmgr_client_usr_uninstall(pkgmgr_client *pc, const char *pkg_type, /******************* end of quote ************************/ /* 6. request install */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_TO_INSTALLER, pkgtype, pkgid, args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "uninstall", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, args)); tryvm_if(ret < 0, ret = PKGMGR_R_ECOMM, "calloc failed"); ret = req_id; @@ -1680,9 +1691,8 @@ API int pkgmgr_client_usr_move(pkgmgr_client *pc, const char *pkg_type, /******************* end of quote ************************/ /* 6. request install */ - ret = comm_client_request(mpc->info.request.cc, req_key, - COMM_REQ_TO_MOVER, pkgtype, pkgid, - args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "move", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, args)); if (ret < 0) { ERR("request failed, ret=%d\n", ret); @@ -1802,7 +1812,8 @@ API int pkgmgr_client_move_usr_pkg(pkgmgr_client *pc, const char *pkg_type, /******************* end of quote ************************/ /* 6. request install */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_TO_MOVER, pkgtype, pkgid, args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "move", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, args)); tryvm_if(ret < 0, ret = PKGMGR_R_ECOMM, "calloc failed"); ret = req_id; @@ -1855,7 +1866,8 @@ API int pkgmgr_client_usr_activate(pkgmgr_client * pc, const char *pkg_type, retvm_if(req_key == NULL, PKGMGR_R_EINVAL, "req_key is NULL"); /* 3. request activate */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_TO_ACTIVATOR, pkgtype, pkgid, "1 PKG", uid, 1); + ret = comm_client_request(mpc->info.request.cc, "activate", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, "1 PKG")); tryvm_if(ret < 0, ret = PKGMGR_R_ECOMM, "request failed, ret=%d", ret); ret = PKGMGR_R_OK; @@ -1901,7 +1913,8 @@ API int pkgmgr_client_usr_deactivate(pkgmgr_client *pc, const char *pkg_type, retvm_if(req_key == NULL, PKGMGR_R_EINVAL, "req_key is NULL"); /* 3. request activate */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_TO_ACTIVATOR, pkgtype, pkgid, "0 PKG", uid, 1); + ret = comm_client_request(mpc->info.request.cc, "deactivate", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, "0 PKG")); tryvm_if(ret < 0, ret = PKGMGR_R_ECOMM, "request failed, ret=%d", ret); ret = PKGMGR_R_OK; @@ -1942,7 +1955,8 @@ API int pkgmgr_client_usr_activate_app(pkgmgr_client * pc, const char *appid, ui retvm_if(req_key == NULL, PKGMGR_R_EINVAL, "req_key is NULL"); /* 3. request activate */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_TO_ACTIVATOR, pkgtype, appid, "1 APP", uid, 1); + ret = comm_client_request(mpc->info.request.cc, "activate", + g_variant_new("(ssss)", req_key, pkgtype, appid, "1 APP")); tryvm_if(ret < 0, ret = PKGMGR_R_ECOMM, "request failed, ret=%d", ret); ret = PKGMGR_R_OK; @@ -2023,7 +2037,8 @@ API int pkgmgr_client_usr_activate_appv(pkgmgr_client * pc, const char *appid, c /******************* end of quote ************************/ /* 3. request activate */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_TO_ACTIVATOR, pkgtype, appid, argsr, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "activate", + g_variant_new("(ssss)", req_key, pkgtype, appid, argsr)); tryvm_if(ret < 0, ret = PKGMGR_R_ECOMM, "request failed, ret=%d", ret); ret = PKGMGR_R_OK; @@ -2067,7 +2082,8 @@ API int pkgmgr_client_usr_deactivate_app(pkgmgr_client *pc, const char *appid, u retvm_if(req_key == NULL, PKGMGR_R_EINVAL, "req_key is NULL"); /* 3. request activate */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_TO_ACTIVATOR, pkgtype, appid, "0 APP", uid, 1); + ret = comm_client_request(mpc->info.request.cc, "deactivate", + g_variant_new("(ssss)", req_key, pkgtype, appid, "0 APP")); tryvm_if(ret < 0, ret = PKGMGR_R_ECOMM, "request failed, ret=%d", ret); ret = PKGMGR_R_OK; @@ -2171,9 +2187,8 @@ API int pkgmgr_client_usr_clear_user_data(pkgmgr_client *pc, const char *pkg_typ /******************* end of quote ************************/ /* 6. request clear */ - ret = comm_client_request(mpc->info.request.cc, req_key, - COMM_REQ_TO_CLEARER, pkgtype, appid, - args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "cleardata", + g_variant_new("(ssss)", req_key, pkgtype, appid, args)); if (ret < 0) { ERR("request failed, ret=%d\n", ret); @@ -2405,7 +2420,8 @@ API int pkgmgr_client_usr_clear_cache_dir(const char *pkgid, uid_t uid) is_type_malloced = 1; } - ret = comm_client_request(pc->info.request.cc, NULL, COMM_REQ_CLEAR_CACHE_DIR, pkg_type, pkgid, NULL, uid, 0); + ret = comm_client_request(pc->info.request.cc, "clearcache", + g_variant_new("(sss)", "reqkey", pkg_type, pkgid)); tryvm_if(ret < 0, ret = PKGMGR_R_ERROR, "COMM_REQ_CLEAR_CACHE_DIR failed, ret=%d\n", ret); ret = PKGMGR_R_OK; @@ -2495,7 +2511,8 @@ API int pkgmgr_client_usr_get_size(pkgmgr_client * pc, const char *pkgid, pkgmgr DBG("[args] %s [len] %d\n", args, len); /* request */ - ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_GET_SIZE, pkgtype, pkgid, args, uid, 1); + ret = comm_client_request(mpc->info.request.cc, "getsize", + g_variant_new("(ssss)", req_key, pkgtype, pkgid, args)); if (ret < 0) ERR("comm_client_request failed, ret=%d\n", ret); diff --git a/comm/comm_client.h b/comm/comm_client.h index 774ac60..731baec 100644 --- a/comm/comm_client.h +++ b/comm/comm_client.h @@ -27,6 +27,7 @@ #ifndef __COMM_CLIENT_H__ #define __COMM_CLIENT_H__ +#include #include "comm_config.h" enum { @@ -41,10 +42,7 @@ typedef void (*status_cb) (void *cb_data, uid_t target_uid, const char *req_id, API comm_client *comm_client_new(void); API int comm_client_free(comm_client *cc); -API int comm_client_request(comm_client *cc, const char *req_id, - const int req_type, const char *pkg_type, - const char *pkgid, const char *args, - uid_t uid, int is_block); +API int comm_client_request(comm_client *cc, const char *method, GVariant *params); API int comm_client_set_status_callback(int comm_status_type, comm_client *cc, status_cb cb, void *cb_data); #endif /* __COMM_CLIENT_H__ */ diff --git a/comm/comm_client_gdbus.c b/comm/comm_client_gdbus.c index 7236fb1..e53dbc7 100644 --- a/comm/comm_client_gdbus.c +++ b/comm/comm_client_gdbus.c @@ -220,9 +220,7 @@ int comm_client_free(comm_client *cc) * Request a message */ int -comm_client_request(comm_client *cc, const char *req_id, const int req_type, - const char *pkg_type, const char *pkgid, const char *args, - uid_t uid, int is_block) +comm_client_request(comm_client *cc, const char *method, GVariant *params) { GError *error = NULL; gint rc = -1; @@ -230,16 +228,6 @@ comm_client_request(comm_client *cc, const char *req_id, const int req_type, GVariant *result = NULL; int retry_cnt = 0; - /* Assign default values if NULL (NULL is not allowed) */ - if (req_id == NULL) - req_id = "tmp_reqid"; - if (pkg_type == NULL) - pkg_type = "none"; - if (pkgid == NULL) - pkgid = ""; - if (args == NULL) - args = ""; - do { proxy = g_dbus_proxy_new_sync(cc->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, COMM_PKGMGR_DBUS_SERVICE, COMM_PKGMGR_DBUS_OBJECT_PATH, @@ -253,7 +241,7 @@ comm_client_request(comm_client *cc, const char *req_id, const int req_type, continue; } - result = g_dbus_proxy_call_sync(proxy, "Request", g_variant_new("(sisssi)", req_id, req_type, pkg_type, pkgid, args, uid), + result = g_dbus_proxy_call_sync(proxy, method, params, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); g_object_unref(proxy); if (result) @@ -272,6 +260,9 @@ comm_client_request(comm_client *cc, const char *req_id, const int req_type, g_variant_get(result, "(i)", &rc); g_variant_unref(result); + if (rc != 0) + ERR("request return code: %d", rc); + return rc == 0 ? COMM_RET_OK : COMM_RET_ERROR; } diff --git a/comm/pkgmgr-installer-client.pc.in b/comm/pkgmgr-installer-client.pc.in index 29f0b83..e1958d2 100644 --- a/comm/pkgmgr-installer-client.pc.in +++ b/comm/pkgmgr-installer-client.pc.in @@ -11,6 +11,6 @@ includedir=@INCLUDEDIR@ Name: package manager installer Description: SLP package manager's installer library Version: @VERSION@ -Requires: +Requires: glib-2.0 Libs: -L${libdir} -lpkgmgr_installer_client Cflags: -I${includedir}/pkgmgr diff --git a/packaging/pkgmgr.spec b/packaging/pkgmgr.spec index f8c3d58..6878c54 100644 --- a/packaging/pkgmgr.spec +++ b/packaging/pkgmgr.spec @@ -19,9 +19,6 @@ Source1008: %{name}.conf BuildRequires: cmake BuildRequires: unzip BuildRequires: gettext-tools -BuildRequires: pkgconfig(cynara-client) -BuildRequires: pkgconfig(cynara-creds-gdbus) -BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(dbus-glib-1) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gio-2.0) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 3406acf..4bdcfc2 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -1,13 +1,10 @@ # package manager server SET(PKGMGR_SERVER "pkgmgr-server") -SET(SRCS src/pkgmgr-server.c src/pm-queue.c) +SET(SRCS src/pkgmgr-server.c src/request.c src/pm-queue.c) pkg_check_modules(SERVER_DEPS REQUIRED gio-2.0 - cynara-client - cynara-creds-gdbus - cynara-session dlog pkgmgr-parser pkgmgr-info diff --git a/server/include/pkgmgr-server.h b/server/include/pkgmgr-server.h index 5ae2bd9..517b5b2 100644 --- a/server/include/pkgmgr-server.h +++ b/server/include/pkgmgr-server.h @@ -23,6 +23,8 @@ #ifndef _PKGMGR_SERVER_H_ #define _PKGMGR_SERVER_H_ +#include + #ifdef LOG_TAG #undef LOG_TAG #endif /* LOG_TAG */ @@ -69,4 +71,8 @@ void _pm_desktop_file_monitor_init(); void _pm_desktop_file_monitor_fini(); int _pm_desktop_file_dir_search(pm_inotify_paths *paths, int number); +gboolean queue_job(void *data); +int __init_request_handler(void); +void __fini_request_handler(void); + #endif/* _PKGMGR_SERVER_H_ */ diff --git a/server/include/pm-queue.h b/server/include/pm-queue.h index bc39dad..b2592f1 100644 --- a/server/include/pm-queue.h +++ b/server/include/pm-queue.h @@ -46,7 +46,9 @@ typedef struct queue_info_map_t { #define MAX_QUEUE_NUM 128 -int _pm_queue_init(); +int _pm_queue_init(void); +pm_dbus_msg *_pm_queue_create_item(uid_t uid, const char *req_id, int req_type, + const char *pkg_type, const char *pkgid, const char *args); int _pm_queue_push(pm_dbus_msg *item); /*position specifies the queue from which to pop request*/ pm_dbus_msg *_pm_queue_pop(int position); diff --git a/server/org.tizen.pkgmgr.conf.in b/server/org.tizen.pkgmgr.conf.in index e9ba1be..266985f 100644 --- a/server/org.tizen.pkgmgr.conf.in +++ b/server/org.tizen.pkgmgr.conf.in @@ -7,7 +7,16 @@ - + + + + + + + + + + diff --git a/server/src/pkgmgr-server.c b/server/src/pkgmgr-server.c index bea0e9c..3f0f4a5 100644 --- a/server/src/pkgmgr-server.c +++ b/server/src/pkgmgr-server.c @@ -39,9 +39,6 @@ #include #include -#include -#include -#include #include #include "pkgmgr_installer.h" @@ -56,8 +53,6 @@ #define OWNER_ROOT 0 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) -static int backend_flag = 0; /* 0 means that backend process is not running */ - typedef struct { char **env; uid_t uid; @@ -71,13 +66,6 @@ Each bit position corresponds to a queue slot which is dynamically determined. */ char backend_busy = 0; -/* -8 bit value to represent quiet mode operation for maximum 8 backends -1->quiet 0->non-quiet -Each bit position corresponds to a queue slot which -is dynamically determined. -*/ -char backend_mode = 63; /*00111111*/ extern int num_of_backends; struct signal_info_t { @@ -92,7 +80,6 @@ static guint pipe_wid; backend_info *begin; extern queue_info_map *start; extern int entries; -static cynara *p_cynara; GMainLoop *mainloop = NULL; @@ -111,12 +98,8 @@ static int __check_queue_status_for_exit(void); static int __is_backend_busy(int position); static void __set_backend_busy(int position); static void __set_backend_free(int position); -static void __set_backend_mode(int position); -static void __unset_backend_mode(int position); static void sighandler(int signo); -static int __get_position_from_pkg_type(char *pkgtype); -gboolean queue_job(void *data); gboolean exit_server(void *data); /* To check whether a particular backend is free/busy*/ @@ -134,16 +117,6 @@ static void __set_backend_free(int position) { backend_busy = backend_busy & ~(1<pkgtype, pkgtype, MAX_PKG_TYPE_LEN)) - return ptr->queue_slot; - else - ptr++; - - } - return -1; -} - static void send_fail_signal(char *pname, char *ptype, char *args) { DBG("send_fail_signal start\n"); @@ -350,7 +257,6 @@ static gboolean pipe_io_handler(GIOChannel *io, GIOCondition cond, gpointer data } __set_backend_free(x); - __set_backend_mode(x); __unset_recovery_mode(ptr->uid, ptr->pkgid, ptr->pkgtype); if (WIFSIGNALED(info.status) || WEXITSTATUS(info.status)) { send_fail_signal(ptr->pkgid, ptr->pkgtype, ptr->args); @@ -431,203 +337,6 @@ static int __register_signal_handler(void) return 0; } -void req_cb(void *cb_data, uid_t uid, const char *req_id, const int req_type, - const char *pkg_type, const char *pkgid, const char *args, - const char *client, const char *session, const char *user, int *ret) -{ - int p; - - DBG(">> in callback >> Got request: [%s] [%d] [%s] [%s] [%s] [%s] [%s] [%s]", - req_id, req_type, pkg_type, pkgid, args, client, session, user); - - pm_dbus_msg *item = calloc(1, sizeof(pm_dbus_msg)); - memset(item, 0x00, sizeof(pm_dbus_msg)); - - strncpy(item->req_id, req_id, sizeof(item->req_id) - 1); - item->req_type = req_type; - strncpy(item->pkg_type, pkg_type, sizeof(item->pkg_type) - 1); - strncpy(item->pkgid, pkgid, sizeof(item->pkgid) - 1); - strncpy(item->args, args, sizeof(item->args) - 1); - item->uid = uid; - /* uid equals to GLOBALUSER means that the installation or action is made at Global level. - * At this time, we are not able to check the credentials of this dbus message (due to gdbus API to implement the pkgmgr-server) - * So we cannot check if the user that makes request has permisssion to do it. - * Note theses CAPI could be used by deamon (user is root or system user) or web/native API framework (user id is one of regular users) - * In consequence a bug is filed : - * - * Logic has to be implmemented: - * RUID means the id of the user that make the request (retreived from credential of the message) - * UID is the uid in argument of the request - * - * if RUID == UID & UID is regular user == TRUE ==> Granted - * if UID == GLOBAL_USER & RUID is ADMIN == TRUE ==> Granted - * if RUID == (ROOT or System USER) & UID is Regular USER ==> Granted - * if UID != Regular USER & UID != GLOBAL USER == TRUE ==> NOT GRANTED - * if RUID == Regular USER & UID != RUID == True ==> NOT GRANTED - * */ - - if (__register_signal_handler()) { - ERR("failed to register signal handler"); - *ret = COMM_RET_ERROR; - goto err; - } - g_idle_add(queue_job, NULL); - - DBG("req_type=(%d) backend_flag=(%d)\n", req_type, backend_flag); - - if (__check_privilege_by_cynara(client, session, user, item->req_type)) { - *ret = PKGMGR_R_EPRIV; - goto err; - } - - switch (item->req_type) { - case COMM_REQ_TO_INSTALLER: - /* quiet mode */ - if (_pm_queue_push(item)) { - ERR("failed to push queue item"); - *ret = COMM_RET_ERROR; - goto err; - } - p = __get_position_from_pkg_type(item->pkg_type); - __set_backend_mode(p); - /* Free resource */ - free(item); - *ret = COMM_RET_OK; - break; - case COMM_REQ_TO_ACTIVATOR: - /* In case of activate, there is no popup */ - if (_pm_queue_push(item)) { - ERR("failed to push queue item"); - *ret = COMM_RET_ERROR; - goto err; - } - p = __get_position_from_pkg_type(item->pkg_type); - __set_backend_mode(p); - /* Free resource */ - free(item); - - *ret = COMM_RET_OK; - break; - case COMM_REQ_TO_CLEARER: - /* In case of clearer, there is no popup */ - if (_pm_queue_push(item)) { - ERR("failed to push queue item"); - *ret = COMM_RET_ERROR; - goto err; - } - p = __get_position_from_pkg_type(item->pkg_type); - /*the backend shows the success/failure popup - so this request is non quiet*/ - __unset_backend_mode(p); - /* Free resource */ - free(item); - - *ret = COMM_RET_OK; - break; - case COMM_REQ_TO_MOVER: - /* In case of mover, there is no popup */ - if (_pm_queue_push(item)) { - ERR("failed to push queue item"); - *ret = COMM_RET_ERROR; - goto err; - } - p = __get_position_from_pkg_type(item->pkg_type); - /*the backend shows the success/failure popup - so this request is non quiet*/ - __unset_backend_mode(p); - /* Free resource */ - free(item); - *ret = COMM_RET_OK; - break; - case COMM_REQ_CANCEL: - _pm_queue_delete(item); - p = __get_position_from_pkg_type(item->pkg_type); - __unset_backend_mode(p); - free(item); - *ret = COMM_RET_OK; - break; - case COMM_REQ_GET_SIZE: - if (_pm_queue_push(item)) { - ERR("failed to push queue item"); - *ret = COMM_RET_ERROR; - goto err; - } - p = __get_position_from_pkg_type(item->pkg_type); - __set_backend_mode(p); - /* Free resource */ - free(item); - *ret = COMM_RET_OK; - break; - - case COMM_REQ_CHECK_APP: - case COMM_REQ_KILL_APP: - /* In case of activate, there is no popup */ - if (_pm_queue_push(item)) { - ERR("failed to push queue item"); - *ret = COMM_RET_ERROR; - goto err; - } - p = __get_position_from_pkg_type(item->pkg_type); - __set_backend_mode(p); - /* Free resource */ - free(item); - - *ret = COMM_RET_OK; - break; - case COMM_REQ_CLEAR_CACHE_DIR: - if (_pm_queue_push(item)) { - ERR("failed to push queue item"); - *ret = COMM_RET_ERROR; - goto err; - } - p = __get_position_from_pkg_type(item->pkg_type); - __set_backend_mode(p); - - *ret = PKGMGR_R_OK; - break; - - default: - DBG("Check your request..\n"); - *ret = COMM_RET_ERROR; - break; - } -err: - if (*ret != COMM_RET_OK) { - DBG("Failed to handle request %s %s\n",item->pkg_type, item->pkgid); - pkgmgr_installer *pi; - gboolean ret_parse; - gint argcp; - gchar **argvp; - GError *gerr = NULL; - - pi = pkgmgr_installer_new(); - if (!pi) { - DBG("Failure in creating the pkgmgr_installer object"); - free(item); - return; - } - - ret_parse = g_shell_parse_argv(args, &argcp, &argvp, &gerr); - if (FALSE == ret_parse) { - DBG("Failed to split args: %s", args); - DBG("messsage: %s", gerr->message); - pkgmgr_installer_free(pi); - free(item); - return; - } - - pkgmgr_installer_receive_request(pi, argcp, argvp); - - pkgmgr_installer_send_signal(pi, item->pkg_type, - item->pkgid, "end", - "fail"); - - pkgmgr_installer_free(pi); - - free(item); - } - return; -} static int __check_backend_status_for_exit(void) { int i = 0; @@ -1314,181 +1023,6 @@ char *_get_backend_cmd(char *type) return NULL; /* cannot find proper command */ } -static int __get_caller_info(GDBusConnection *connection, - GDBusMethodInvocation *invocation, - char **client, char **user, char **session) -{ - const gchar *sender = NULL; - pid_t pid; - int ret = 0; - int r; - char buf[BUFMAX] = {0, }; - - do { - sender = g_dbus_method_invocation_get_sender(invocation); - if (sender == NULL) { - ERR("get sender failed"); - ret = COMM_RET_ERROR; - break; - } - - r = cynara_creds_gdbus_get_client(connection, sender, - CLIENT_METHOD_DEFAULT, client); - if (r != CYNARA_API_SUCCESS) { - cynara_strerror(r, buf, BUFMAX); - ERR("cynara_creds_dbus_get_client failed: %s", buf); - ret = COMM_RET_ERROR; - break; - } - - r = cynara_creds_gdbus_get_user(connection, sender, - USER_METHOD_DEFAULT, user); - if (r != CYNARA_API_SUCCESS) { - cynara_strerror(r, buf, BUFMAX); - ERR("cynara_creds_dbus_get_user failed: %s", buf); - ret = COMM_RET_ERROR; - break; - } - - r = cynara_creds_gdbus_get_pid(connection, sender, &pid); - if (r != CYNARA_API_SUCCESS) { - cynara_strerror(r, buf, BUFMAX); - ERR("cynara_creds_dbus_get_pid failed: %s", buf); - ret = COMM_RET_ERROR; - break; - } - - *session = cynara_session_from_pid(pid); - if (*session == NULL) { - ERR("cynara_session_from_pid failed"); - ret = COMM_RET_ERROR; - break; - } - DBG("session: %s", session); - } while (0); - - return ret; -} - -static void __handle_method_call(GDBusConnection *connection, - const gchar *sender, const gchar *object_path, - const gchar *interface_name, const gchar *method_name, - GVariant *parameters, GDBusMethodInvocation *invocation, - gpointer user_data) -{ - gchar *req_id = NULL; - gint req_type = -1; - gchar *pkg_type = NULL; - gchar *pkgid = NULL; - gchar *args = NULL; - gint uid = -1; - gint ret = -1; - char *client; - char *user; - char *session; - - if (g_strcmp0(method_name, "Request") != 0) { - ERR("unknown method call"); - return; - } - - if (__get_caller_info(connection, invocation, &client, &user, - &session)) { - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", ret)); - return; - } - - g_variant_get(parameters, "(&si&s&s&si)", &req_id, &req_type, &pkg_type, - &pkgid, &args, &uid); - if (req_id == NULL || req_type == -1 || pkg_type == NULL || - pkgid == NULL || args == NULL || uid == -1) { - ERR("failed to get parameters"); - free(client); - free(user); - free(session); - return; - } - - req_cb(NULL, uid, req_id, req_type, pkg_type, pkgid, args, - client, session, user, &ret); - - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", ret)); - - free(client); - free(user); - free(session); -} - -static const char instropection_xml[] = - "" - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - ""; -static const GDBusInterfaceVTable interface_vtable = -{ - __handle_method_call, - NULL, - NULL, -}; -static GDBusNodeInfo *instropection_data; -static guint reg_id; -static guint owner_id; - -static void __on_bus_acquired(GDBusConnection *connection, const gchar *name, - gpointer user_data) -{ - - DBG("on bus acquired"); - - reg_id = g_dbus_connection_register_object(connection, - COMM_PKGMGR_DBUS_OBJECT_PATH, - instropection_data->interfaces[0], - &interface_vtable, NULL, NULL, NULL); - - if (reg_id < 0) - ERR("failed to register object"); -} - -static void __on_name_acquired(GDBusConnection *connection, const gchar *name, - gpointer user_data) -{ - DBG("on name acquired: %s", name); -} - -static void __on_name_lost(GDBusConnection *connection, const gchar *name, - gpointer user_data) -{ - DBG("on name lost: %s", name); -} - -static int __init_dbus(void) -{ - instropection_data = g_dbus_node_info_new_for_xml(instropection_xml, NULL); - - owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, COMM_PKGMGR_DBUS_SERVICE, - G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired, - __on_name_acquired, __on_name_lost, NULL, NULL); - - return 0; -} - -static void __fini_dbus(void) -{ - g_bus_unown_name(owner_id); - g_dbus_node_info_unref(instropection_data); -} - int main(int argc, char *argv[]) { FILE *fp_status = NULL; @@ -1554,15 +1088,14 @@ err: return -1; } - r = cynara_initialize(&p_cynara, NULL); - if (r != CYNARA_API_SUCCESS) { - ERR("cynara initialize failed with code=%d", r); + r = __init_request_handler(); + if (r) { + ERR("dbus init failed"); return -1; } - r = __init_dbus(); - if (r) { - ERR("dbus init failed"); + if (__register_signal_handler()) { + ERR("failed to register signal handler"); return -1; } @@ -1580,8 +1113,7 @@ err: g_main_loop_run(mainloop); DBG("Quit main loop."); - __fini_dbus(); - cynara_finish(p_cynara); + __fini_request_handler(); __fini_backend_info(); _pm_queue_final(); diff --git a/server/src/pm-queue.c b/server/src/pm-queue.c index e862671..9addbcd 100644 --- a/server/src/pm-queue.c +++ b/server/src/pm-queue.c @@ -136,7 +136,7 @@ static pm_queue_data *__get_head_from_pkgtype(pm_dbus_msg *item) } -int _pm_queue_init() +int _pm_queue_init(void) { /*Find the num of backends currently supported and initialize that many queues. It is dynamically determined.*/ @@ -257,6 +257,28 @@ int _pm_queue_init() return 0; } +pm_dbus_msg *_pm_queue_create_item(uid_t uid, const char *req_id, + int req_type, const char *pkg_type, const char *pkgid, + const char *args) +{ + pm_dbus_msg *item; + + item = calloc(1, sizeof(pm_dbus_msg)); + if (item == NULL) { + ERR("Fail to allocate memory"); + return NULL; + } + + item->uid = uid; + snprintf(item->req_id, sizeof(item->req_id), "%s", req_id); + item->req_type = req_type; + snprintf(item->pkg_type, sizeof(item->pkg_type), "%s", pkg_type); + snprintf(item->pkgid, sizeof(item->pkgid), "%s", pkgid); + snprintf(item->args, sizeof(item->args), "%s", args); + + return item; +} + int _pm_queue_push(pm_dbus_msg *item) { pm_queue_data *data = NULL; diff --git a/server/src/request.c b/server/src/request.c new file mode 100644 index 0000000..5f94498 --- /dev/null +++ b/server/src/request.c @@ -0,0 +1,447 @@ +#include + +#include +#include + +#include "comm_config.h" +#include "pm-queue.h" +#include "pkgmgr-server.h" +#include "package-manager-debug.h" + +static const char instropection_xml[] = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; +static GDBusNodeInfo *instropection_data; +static guint reg_id; +static guint owner_id; + +static int __handle_request_install(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgpath; + gchar *args; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s&s)", &reqid, &pkgtype, &pkgpath, + &args); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_TO_INSTALLER, + pkgtype, pkgpath, args); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static int __handle_request_reinstall(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgid; + gchar *args; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s&s)", &reqid, &pkgtype, &pkgid, + &args); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_TO_INSTALLER, + pkgtype, pkgid, args); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static int __handle_request_uninstall(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgid; + gchar *args; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s&s)", &reqid, &pkgtype, &pkgid, + &args); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_TO_INSTALLER, + pkgtype, pkgid, args); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static int __handle_request_cleardata(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgid; + gchar *args; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s&s)", &reqid, &pkgtype, &pkgid, + &args); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_TO_CLEARER, + pkgtype, pkgid, args); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static int __handle_request_move(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgid; + gchar *args; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s&s)", &reqid, &pkgtype, &pkgid, + &args); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_TO_MOVER, + pkgtype, pkgid, args); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static int __handle_request_activate(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgid; + gchar *args; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s&s)", &reqid, &pkgtype, &pkgid, + &args); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_TO_ACTIVATOR, + pkgtype, pkgid, args); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static int __handle_request_deactivate(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgid; + gchar *args; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s&s)", &reqid, &pkgtype, &pkgid, + &args); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_TO_ACTIVATOR, + pkgtype, pkgid, args); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static int __handle_request_getsize(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgid; + gchar *args; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s&s)", &reqid, &pkgtype, &pkgid, + &args); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_GET_SIZE, + pkgtype, pkgid, args); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static int __handle_request_clearcache(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgid; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s)", &reqid, &pkgtype, &pkgid); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_CLEAR_CACHE_DIR, + pkgtype, pkgid, NULL); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static int __handle_request_kill(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgid; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s)", &reqid, &pkgtype, &pkgid); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_KILL_APP, + pkgtype, pkgid, NULL); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static int __handle_request_check(uid_t uid, GVariant *parameters) +{ + gchar *reqid; + gchar *pkgtype; + gchar *pkgid; + pm_dbus_msg *item; + + g_variant_get(parameters, "(&s&s&s)", &reqid, &pkgtype, &pkgid); + + item = _pm_queue_create_item(uid, reqid, COMM_REQ_CHECK_APP, + pkgtype, pkgid, NULL); + if (item == NULL) + return -1; + + if (_pm_queue_push(item)) + return -1; + + return 0; +} + +static uid_t __get_caller_uid(GDBusConnection *connection, const char *name) +{ + GError *err = NULL; + GVariant *result; + uid_t uid; + + result = g_dbus_connection_call_sync(connection, + "org.freedesktop.DBus", "/org/freedesktop/DBus", + "org.freedesktop.DBus", "GetConnectionUnixUser", + g_variant_new("(s)", name), NULL, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + if (result == NULL) { + ERR("failed to get caller uid: %s", err->message); + g_error_free(err); + return (uid_t)-1; + } + + g_variant_get(result, "(u)", &uid); + + return uid; +} + +static void __handle_method_call(GDBusConnection *connection, + const gchar *sender, const gchar *object_path, + const gchar *interface_name, const gchar *method_name, + GVariant *parameters, GDBusMethodInvocation *invocation, + gpointer user_data) +{ + int ret; + uid_t uid; + + uid = __get_caller_uid(connection, + g_dbus_method_invocation_get_sender(invocation)); + if (uid == (uid_t)-1) + return; + + if (g_strcmp0(method_name, "install") == 0) + ret = __handle_request_install(uid, parameters); + else if (g_strcmp0(method_name, "reinstall") == 0) + ret = __handle_request_reinstall(uid, parameters); + else if (g_strcmp0(method_name, "uninstall") == 0) + ret = __handle_request_uninstall(uid, parameters); + else if (g_strcmp0(method_name, "cleardata") == 0) + ret = __handle_request_cleardata(uid, parameters); + else if (g_strcmp0(method_name, "move") == 0) + ret = __handle_request_move(uid, parameters); + else if (g_strcmp0(method_name, "activate") == 0) + ret = __handle_request_activate(uid, parameters); + else if (g_strcmp0(method_name, "deactivate") == 0) + ret = __handle_request_deactivate(uid, parameters); + else if (g_strcmp0(method_name, "getsize") == 0) + ret = __handle_request_getsize(uid, parameters); + else if (g_strcmp0(method_name, "clearcache") == 0) + ret = __handle_request_clearcache(uid, parameters); + else if (g_strcmp0(method_name, "kill") == 0) + ret = __handle_request_kill(uid, parameters); + else if (g_strcmp0(method_name, "check") == 0) + ret = __handle_request_check(uid, parameters); + else + ret = -1; + + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", ret)); + + if (ret == 0) + g_idle_add(queue_job, NULL); +} + +static const GDBusInterfaceVTable interface_vtable = +{ + __handle_method_call, + NULL, + NULL, +}; + +static void __on_bus_acquired(GDBusConnection *connection, const gchar *name, + gpointer user_data) +{ + + DBG("on bus acquired"); + + reg_id = g_dbus_connection_register_object(connection, + COMM_PKGMGR_DBUS_OBJECT_PATH, + instropection_data->interfaces[0], + &interface_vtable, NULL, NULL, NULL); + + if (reg_id < 0) + ERR("failed to register object"); +} + +static void __on_name_acquired(GDBusConnection *connection, const gchar *name, + gpointer user_data) +{ + DBG("on name acquired: %s", name); +} + +static void __on_name_lost(GDBusConnection *connection, const gchar *name, + gpointer user_data) +{ + DBG("on name lost: %s", name); +} + +int __init_request_handler(void) +{ + instropection_data = g_dbus_node_info_new_for_xml(instropection_xml, NULL); + + owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, COMM_PKGMGR_DBUS_SERVICE, + G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired, + __on_name_acquired, __on_name_lost, NULL, NULL); + + return 0; +} + +void __fini_request_handler(void) +{ + g_bus_unown_name(owner_id); + g_dbus_node_info_unref(instropection_data); +} -- 2.7.4