--- /dev/null
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "libds/log.h"
+
+#include "util.h"
+
+#ifdef HAVE_CYNARA
+#include <cynara-session.h>
+#include <cynara-client.h>
+#include <cynara-creds-socket.h>
+#include <sys/smack.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#define CYNARA_BUFSIZE 128
+
+static cynara *g_cynara = NULL;
+static int g_cynara_refcount = 0;
+
+static void
+__security_log_print(int err, const char *fmt, ...)
+{
+ int ret;
+ va_list args;
+ char buf[CYNARA_BUFSIZE] = "\0";
+ char tmp[CYNARA_BUFSIZE + CYNARA_BUFSIZE] = "\0";
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(tmp, CYNARA_BUFSIZE + CYNARA_BUFSIZE, fmt, args);
+ va_end(args);
+ }
+
+ ret = cynara_strerror(err, buf, CYNARA_BUFSIZE);
+ if (ret != CYNARA_API_SUCCESS) {
+ ds_err("Failed to get cynara_strerror. error : %d (error log about %s: %d)\n", ret, tmp, err);
+ return;
+ }
+
+ ds_err("%s is failed. (%s)\n", tmp, buf);
+}
+#endif
+
+bool
+tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege)
+{
+#ifdef HAVE_CYNARA
+ bool res = false;
+ char *client_smack = NULL;
+ char *client_session = NULL;
+ char uid_str[16] = { 0, };
+ int len = -1;
+ int ret = -1;
+
+ /* If cynara_initialize() has been (retried) and failed, we suppose that cynara is not available. */
+ /* Then we return true as if there is no security check available. */
+ if (!g_cynara)
+ return true;
+
+ if (!g_cynara) {
+ ds_err("security has not been initialized.\n");
+ return false;
+ }
+
+ ret = smack_new_label_from_process((int)pid, &client_smack);
+ if (ret <= 0)
+ goto finish;
+
+ snprintf(uid_str, 15, "%d", (int)uid);
+
+ client_session = cynara_session_from_pid(pid);
+ if (!client_session)
+ goto finish;
+
+ ret = cynara_check(g_cynara, client_smack, client_session,
+ uid_str, privilege);
+
+ if (ret == CYNARA_API_ACCESS_ALLOWED)
+ res = true;
+ else
+ __security_log_print(ret, "privilege: %s, client_smack: %s, pid: %d", privilege, client_smack, pid);
+
+finish:
+ ds_dbg("Privilege Check For '%s' %s pid:%u uid:%u client_smack:%s(len:%d) client_session:%s ret:%d",
+ privilege, res ? "SUCCESS" : "FAIL", pid, uid,
+ client_smack ? client_smack : "N/A", len,
+ client_session ? client_session: "N/A", ret);
+
+ if (client_session)
+ free(client_session);
+ if (client_smack)
+ free(client_smack);
+
+ return res;
+#else
+ return true;
+#endif
+}
+
+int
+tizen_security_init(void)
+{
+#ifdef HAVE_CYNARA
+ int ret = CYNARA_API_SUCCESS;
+ int retry_cnt = 0;
+ static bool retried = false;
+
+ if (++g_cynara_refcount != 1)
+ return g_cynara_refcount;
+
+ if (!g_cynara && false == retried) {
+ retried = true;
+
+ for (retry_cnt = 0; retry_cnt < 5; retry_cnt++) {
+ ds_dbg("Retry cynara initialize: %d\n", retry_cnt + 1);
+
+ ret = cynara_initialize(&g_cynara, NULL);
+
+ if (CYNARA_API_SUCCESS == ret) {
+ ds_dbg("Succeed to initialize cynara !\n");
+ return 1;
+ }
+
+ __security_log_print(ret, "cynara_initialize");
+ g_cynara = NULL;
+ }
+ }
+
+ ds_err("Failed to initialize _security ! (error:%d, retry_cnt=%d)\n",
+ ret, retry_cnt);
+ --g_cynara_refcount;
+
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+void
+tizen_security_finish(void)
+{
+#ifdef HAVE_CYNARA
+ if (g_cynara_refcount < 1) {
+ ds_err("%s called without tizen_security_init\n", __FUNCTION__);
+ return 0;
+ }
+
+ if (--g_cynara_refcount != 0)
+ return 1;
+
+ if (g_cynara) {
+ cynara_finish(g_cynara);
+ g_cynara = NULL;
+ }
+#endif
+
+ return 1;
+}
+