Exclude some lines for code coverage
[platform/core/api/package-manager.git] / src / package_manager_internal.c
index c16952c..c058f63 100644 (file)
  * limitations under the License.
  */
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/syscall.h>
 #include <unistd.h>
+#include <pthread.h>
 
 #include <package-manager.h>
 #include <pkgmgr-info.h>
 #include <tzplatform_config.h>
+#include <cynara-client.h>
+#include <cynara-session.h>
 
 #include "package_info.h"
 #include "package_manager.h"
 #include "package_manager_internal.h"
 
-#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
+#define MAX_SMACK_LABEL_LEN 255
+#define gettid() syscall(SYS_gettid)
 
-typedef struct _foreach_pkg_context_{
+typedef struct _foreach_pkg_context_ {
        package_manager_package_info_cb callback;
        void *user_data;
 } foreach_pkg_context_s;
 
+static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER;
+
+int check_privilege(privilege_type type)
+{
+       cynara *p_cynara;
+       int fd;
+       int ret;
+       char subject_label[MAX_SMACK_LABEL_LEN + 1] = { 0 };
+       char uid[10];
+       char *session;
+       const char *privilege;
+       pid_t pid = getpid();
+       pid_t tid = gettid();
+
+       if (pid == tid) {
+               fd = open("/proc/self/attr/current", O_RDONLY);
+       } else {
+               /* LCOV_EXCL_START */
+               // Check current thread smack label.
+               char path[256] = { 0 };
+               pid = tid;
+               snprintf(path, sizeof(path), "/proc/%d/attr/current", tid);
+               fd = open(path, O_RDONLY);
+               /* LCOV_EXCL_STOP */
+       }
+       if (fd < 0) {
+               /* LCOV_EXCL_START */
+               LOGE("open failed: %d", errno);
+               return PACKAGE_MANAGER_ERROR_IO_ERROR;
+               /* LCOV_EXCL_STOP */
+       }
+
+       ret = read(fd, subject_label, MAX_SMACK_LABEL_LEN);
+       if (ret < 0) {
+               /* LCOV_EXCL_START */
+               LOGE("read failed: %d", errno);
+               close(fd);
+               return PACKAGE_MANAGER_ERROR_IO_ERROR;
+               /* LCOV_EXCL_STOP */
+       }
+       close(fd);
+
+       pthread_mutex_lock(&__mutex);
+       ret = cynara_initialize(&p_cynara, NULL);
+       if (ret != CYNARA_API_SUCCESS) {
+               /* LCOV_EXCL_START */
+               LOGE("init cynara failed: %d", ret);
+               pthread_mutex_unlock(&__mutex);
+               return PACKAGE_MANAGER_ERROR_IO_ERROR;
+               /* LCOV_EXCL_STOP */
+       }
+
+       snprintf(uid, 10, "%d", getuid());
+       session = cynara_session_from_pid(pid);
+
+       switch (type) {
+       case PRIVILEGE_PACKAGE_MANAGER_INFO:
+               privilege = "http://tizen.org/privilege/packagemanager.info";
+               break;
+       /* LCOV_EXCL_START */
+       case PRIVILEGE_PACKAGE_MANAGER_ADMIN:
+               privilege = "http://tizen.org/privilege/packagemanager.admin";
+               break;
+       /* LCOV_EXCL_STOP */
+       case PRIVILEGE_PACKAGE_MANAGER_CACHE:
+               privilege =
+                       "http://tizen.org/privilege/packagemanager.clearcache";
+               break;
+       /* LCOV_EXCL_START */
+       default:
+               privilege = NULL;
+               break;
+       /* LCOV_EXCL_STOP */
+       }
+
+       ret = cynara_check(p_cynara, subject_label, session, uid, privilege);
+
+       free(session);
+       cynara_finish(p_cynara);
+       pthread_mutex_unlock(&__mutex);
+
+       if (ret != CYNARA_API_ACCESS_ALLOWED) {
+               /* LCOV_EXCL_START */
+               LOGE("cynara access check failed: %d", ret);
+               return PACKAGE_MANAGER_ERROR_PERMISSION_DENIED;
+               /* LCOV_EXCL_STOP */
+       }
+
+       return PACKAGE_MANAGER_ERROR_NONE;
+}
+
 static const char *package_manager_error_to_string(package_manager_error_e
                                                   error)
 {
@@ -39,18 +138,48 @@ static const char *package_manager_error_to_string(package_manager_error_e
                return "NONE";
        case PACKAGE_MANAGER_ERROR_INVALID_PARAMETER:
                return "INVALID_PARAMETER";
+       /* LCOV_EXCL_START */
        case PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY:
                return "OUT_OF_MEMORY";
+       /* LCOV_EXCL_STOP */
        case PACKAGE_MANAGER_ERROR_IO_ERROR:
                return "IO_ERROR";
        case PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE:
                return "NO_SUCH_PACKAGE";
+       /* LCOV_EXCL_START */
        case PACKAGE_MANAGER_ERROR_PERMISSION_DENIED:
                return "PERMISSION_DENIED";
        case PACKAGE_MANAGER_ERROR_SYSTEM_ERROR:
                return "SEVERE_SYSTEM_ERROR";
        default:
                return "UNKNOWN";
+       /* LCOV_EXCL_STOP */
+       }
+}
+
+int package_manager_convert_internal_error(int internal_error)
+{
+       switch (internal_error) {
+       case PKGMGR_R_ERROR:
+       case PKGMGR_R_ECOMM:
+       case PKGMGR_R_ESYSTEM:
+               return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR;
+       case PKGMGR_R_EINVAL:
+               return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
+       case PKGMGR_R_ETIMEOUT:
+       case PKGMGR_R_EPRIV:
+               return PACKAGE_MANAGER_ERROR_PERMISSION_DENIED;
+       case PKGMGR_R_ENOPKG:
+               return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE;
+       case PKGMGR_R_ENOMEM:
+               return PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY;
+       case PKGMGR_R_EIO:
+               return PACKAGE_MANAGER_ERROR_IO_ERROR;
+       /* LCOV_EXCL_START */
+       default:
+               _LOGE("Unexpected error");
+               return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR;
+       /* LCOV_EXCL_STOP */
        }
 }
 
@@ -58,9 +187,11 @@ int package_manager_error(package_manager_error_e error,
                                 const char *function, const char *description)
 {
        if (description) {
+               /* LCOV_EXCL_START */
                _LOGE("[%s] %s(0x%08x) : %s", function,
                     package_manager_error_to_string(error), error,
                     description);
+               /* LCOV_EXCL_STOP */
        } else {
                _LOGE("[%s] %s(0x%08x)", function,
                     package_manager_error_to_string(error), error);
@@ -74,28 +205,31 @@ int package_info_get_package_info(const char *package, package_info_h *package_i
        return package_info_create(package, package_info);
 }
 
-static int package_info_foreach_package_info_cb(const pkgmgr_pkginfo_h handle, void *user_data)
+static int package_info_foreach_package_info_cb(const pkgmgrinfo_pkginfo_h handle, void *user_data)
 {
-       char *pkg_name = NULL;
        foreach_pkg_context_s *foreach_pkg_context = user_data;
        package_info_h package_info = NULL;
        bool r = false;
+       int ret;
 
-       if (handle == NULL || foreach_pkg_context == NULL)
-       {
+       if (handle == NULL || foreach_pkg_context == NULL) {
+               /* LCOV_EXCL_START */
                package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
-               return PKGMGR_R_EINVAL;
+               return PMINFO_R_EINVAL;
+               /* LCOV_EXCL_STOP */
        }
 
-       pkgmgr_pkginfo_get_pkgname(handle, &pkg_name);
+       ret = package_info_create_with_pkginfo(handle, &package_info);
+       if (ret != PACKAGE_MANAGER_ERROR_NONE)
+               /* LCOV_EXCL_START */
+               return package_manager_error(ret, __FUNCTION__, NULL);
+               /* LCOV_EXCL_STOP */
 
-       if (package_info_create(pkg_name, &package_info) == PACKAGE_MANAGER_ERROR_NONE)
-       {
-               r = foreach_pkg_context->callback(package_info, foreach_pkg_context->user_data);
-               package_info_destroy(package_info);
-       }
+       r = foreach_pkg_context->callback(package_info, foreach_pkg_context->user_data);
 
-       return (r == true) ? PKGMGR_R_OK : PKGMGR_R_ERROR;
+       package_info_destroy_handle(package_info);
+
+       return (r == true) ? PMINFO_R_OK : PMINFO_R_ERROR;
 }
 
 int package_info_foreach_package_info(package_manager_package_info_cb callback, void *user_data)
@@ -107,17 +241,14 @@ int package_info_foreach_package_info(package_manager_package_info_cb callback,
        int ret = 0;
 
        if (callback == NULL)
-       {
                return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
-       }
-       uid_t uid = getuid();
-       if (uid != GLOBAL_USER)
-               ret = pkgmgr_pkginfo_get_usr_list(package_info_foreach_package_info_cb, &foreach_pkg_context, uid);
-       else
-               ret = pkgmgr_pkginfo_get_list(package_info_foreach_package_info_cb, &foreach_pkg_context);
-       if (ret < 0) {
+
+       ret = pkgmgrinfo_pkginfo_get_list(package_info_foreach_package_info_cb, &foreach_pkg_context);
+
+       if (ret < 0)
+               /* LCOV_EXCL_START */
                return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE;
-       }
+               /* LCOV_EXCL_STOP */
 
        return PACKAGE_MANAGER_ERROR_NONE;
 }
@@ -129,20 +260,16 @@ int package_info_filter_foreach_package_info(pkgmgrinfo_pkginfo_filter_h handle,
                .user_data = user_data,
        };
        int ret;
-       uid_t uid;
 
        if ((handle == NULL) || (callback == NULL))
                return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
 
-       uid = getuid();
-       if (uid != GLOBAL_USER)
-               ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, package_info_foreach_package_info_cb, &foreach_pkg_context, uid);
-       else
-               ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle, package_info_foreach_package_info_cb, &foreach_pkg_context);
+       ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle, package_info_foreach_package_info_cb, &foreach_pkg_context);
 
        if (ret < 0)
+               /* LCOV_EXCL_START */
                return PACKAGE_MANAGER_ERROR_IO_ERROR;
+               /* LCOV_EXCL_STOP */
 
        return PACKAGE_MANAGER_ERROR_NONE;
 }
-