From: Ji Yong Min Date: Thu, 9 Jul 2015 04:42:08 +0000 (+0900) Subject: Add multi-user activation X-Git-Tag: accepted/tizen/mobile/20150709.111132^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e4476e39af66a4996356f0fb50ff408d4b607bd3;p=platform%2Fcore%2Fapi%2Fmedia-controller.git Add multi-user activation - modify to setup db in user-session - modify to use db to read & write by uid(use db in user-session) - modify service to root daemon temporary - remove smack labels Change-Id: I5aec404dc9d5c3a7c8d01767c15b82623a867100 Signed-off-by: Jiyong Min --- diff --git a/include/media_controller_db.h b/include/media_controller_db.h index 9a79341..1bdb956 100755 --- a/include/media_controller_db.h +++ b/include/media_controller_db.h @@ -21,7 +21,7 @@ #include #include -#define MC_DB_NAME tzplatform_mkpath(TZ_SYS_DB, ".media_controller.db") +#define MC_DB_NAME ".media_controller.db" #define MC_DB_TABLE_SERVER_LIST "server_list" #define MC_DB_TABLE_LATEST_SERVER "latest_server" diff --git a/packaging/capi-media-controller.spec b/packaging/capi-media-controller.spec index 4f61058..d50c8a1 100755 --- a/packaging/capi-media-controller.spec +++ b/packaging/capi-media-controller.spec @@ -1,15 +1,16 @@ Name: capi-media-controller Summary: Multimedia Controller for player application -Version: 0.0.3 +Version: 0.0.4 Release: 1 Group: System/Libraries License: Apache-2.0 Source0: %{name}-%{version}.tar.gz Source1: mediacontroller.service Source2: mediacontroller.socket +Source3: media-controller-user.service Source1001: media-controller_create_db.sh -Requires(post): /sbin/ldconfig -Requires(postun): /sbin/ldconfig +#Requires(post): /sbin/ldconfig +#Requires(postun): /sbin/ldconfig BuildRequires: cmake BuildRequires: sqlite BuildRequires: pkgconfig(capi-base-common) @@ -63,29 +64,28 @@ install -m 644 %{SOURCE1} %{buildroot}%{_unitdir}/mediacontroller.service install -m 644 %{SOURCE2} %{buildroot}%{_unitdir}/mediacontroller.socket ln -s ../mediacontroller.socket %{buildroot}%{_unitdir}/sockets.target.wants/mediacontroller.socket -#Create DB +# Setup DB creation in user session +mkdir -p %{buildroot}%{_unitdir_user}/default.target.wants/ +install -m 644 %{SOURCE3} %{buildroot}%{_unitdir_user}/media-controller-user.service +ln -sf ../media-controller-user.service %{buildroot}%{_unitdir_user}/default.target.wants/media-controller-user.service + +# Create DB for multi-user mkdir -p %{buildroot}%{_bindir} install -m 0775 %{SOURCE1001} %{buildroot}%{_bindir}/media-controller_create_db.sh -mkdir -p %{buildroot}%{TZ_SYS_DB} -sqlite3 %{buildroot}%{TZ_SYS_DB}/.media_controller.db 'PRAGMA journal_mode = PERSIST; PRAGMA user_version=1;' mkdir -p %{buildroot}/usr/share/license cp LICENSE.APLv2.0 %{buildroot}/usr/share/license/%{name} -%post -p /sbin/ldconfig +%post chgrp %TZ_SYS_USER_GROUP %{_bindir}/media-controller_create_db.sh -%postun -p /sbin/ldconfig +%postun %files %defattr(-,root,root,-) %{_libdir}/*.so.* %{_bindir}/media-controller_create_db.sh #%{_bindir}/* //disable tests -%manifest capi-media-controller.manifest -%attr(660,system,app) %{TZ_SYS_DB}/.media_controller.db -%attr(660,system,app) %{TZ_SYS_DB}/.media_controller.db-journal -%config(noreplace) %{TZ_SYS_DB}/.media_controller.db -%config(noreplace) %{TZ_SYS_DB}/.media_controller.db-journal +%manifest %{name}.manifest /usr/share/license/%{name} %files -n mediacontroller @@ -95,8 +95,8 @@ chgrp %TZ_SYS_USER_GROUP %{_bindir}/media-controller_create_db.sh %{_unitdir}/mediacontroller.service %{_unitdir}/mediacontroller.socket %{_unitdir}/sockets.target.wants/mediacontroller.socket -#change owner -#chown 200:5000 %{TZ_SYS_DB}/.media_controller.db* +%{_unitdir_user}/media-controller-user.service +%{_unitdir_user}/default.target.wants/media-controller-user.service %files devel %defattr(-,root,root,-) diff --git a/packaging/media-controller-user.service b/packaging/media-controller-user.service new file mode 100755 index 0000000..a7b5e1a --- /dev/null +++ b/packaging/media-controller-user.service @@ -0,0 +1,12 @@ +[Unit] +Description=Media controller user + +[Service] +Type=idle +CPUAccounting=true +CPUQuota=5% +ExecStartPre=/usr/bin/sleep 5 +ExecStart=/usr/bin/sh -c "/usr/bin/media-controller_create_db.sh" + +[Install] +WantedBy=default.target diff --git a/packaging/media-controller_create_db.sh b/packaging/media-controller_create_db.sh index a112bce..c691ca7 100755 --- a/packaging/media-controller_create_db.sh +++ b/packaging/media-controller_create_db.sh @@ -2,16 +2,23 @@ source /etc/tizen-platform.conf -mkdir -p $TZ_SYS_DB +mkdir -p $TZ_USER_DB #Create DB file -sqlite3 ${TZ_SYS_DB}/.media_controller.db 'PRAGMA journal_mode = PERSIST;' +sqlite3 ${TZ_USER_DB}/.media_controller.db 'PRAGMA journal_mode = PERSIST; + CREATE TABLE IF NOT EXISTS latest_server (server_name TEXT PRIMARY KEY); +' #Change permission -chmod 664 ${TZ_SYS_DB}/.media_controller.db -chmod 664 ${TZ_SYS_DB}/.media_controller.db-journal +chmod 644 ${TZ_USER_DB}/.media_controller.db +chmod 644 ${TZ_USER_DB}/.media_controller.db-journal + +#if [ -f /opt/usr/dbspace/.media_controller.db ] +#then +# chsmack -a 'mediacontroller::db' /opt/usr/dbspace/.media_controller.db* +#fi #Change group (6017: db_filemanager 5000: app) -chgrp $TZ_SYS_USER_GROUP ${TZ_SYS_DB} -chgrp 6017 ${TZ_SYS_DB}/.media_controller.db -chgrp 6017 ${TZ_SYS_DB}/.media_controller.db-journal +chgrp $TZ_SYS_USER_GROUP ${TZ_USER_DB} +chgrp 6017 ${TZ_USER_DB}/.media_controller.db +chgrp 6017 ${TZ_USER_DB}/.media_controller.db-journal diff --git a/packaging/mediacontroller.service b/packaging/mediacontroller.service index 035f1a7..f8fd79d 100755 --- a/packaging/mediacontroller.service +++ b/packaging/mediacontroller.service @@ -2,11 +2,8 @@ Description=Media controller [Service] -User=system -Group=system -SmackProcessLabel=mediacontroller ExecStart=/usr/bin/mediacontroller Type=simple [Install] -WantedBy=multi-user.target +Also=mediacontroller.socket diff --git a/packaging/mediacontroller.socket b/packaging/mediacontroller.socket index 12e08ee..e1db656 100755 --- a/packaging/mediacontroller.socket +++ b/packaging/mediacontroller.socket @@ -4,9 +4,7 @@ Description=MediaController Service socket [Socket] SocketUser=system SocketGroup=system -ListenStream=/var/run/mediacontroller/media_sa_controller -SmackLabelIPIn=mediacontroller -SmackLabelIPOut=mediacontroller +ListenStream=/var/run/media-controller/media_sa_controller Service=mediacontroller.service [Install] diff --git a/src/media_controller_db.c b/src/media_controller_db.c index d58ea3a..6b99458 100755 --- a/src/media_controller_db.c +++ b/src/media_controller_db.c @@ -13,6 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include +#include +#include +#include +#include +#include +#include #include "media_controller_private.h" #include "media_controller_db.h" @@ -38,6 +46,9 @@ typedef enum { MC_SERVER_FIELD_REPEAT_MODE, } server_table_field_e; +#define FAT_FILEPATH_LEN_MAX 4096 /* inc null */ +#define MC_FILE_PATH_LEN_MAX FAT_FILEPATH_LEN_MAX /**< File path max length (include file name) on file system */ + static int __mc_db_busy_handler(void *pData, int count) { usleep(50000); @@ -166,6 +177,63 @@ static int __mc_db_get_ulong_value_of_key(void *handle, const char *server_name, return MEDIA_CONTROLLER_ERROR_NONE; } +static char* __mc_get_db_name(uid_t uid) +{ + char result_psswd[MC_FILE_PATH_LEN_MAX]; + char *result_psswd_rtn = NULL; + struct group *grpinfo = NULL; + char * dir = NULL; + + memset(result_psswd, 0, sizeof(result_psswd)); + if(uid == getuid()) + { + strncpy(result_psswd, MC_DB_NAME, sizeof(result_psswd)); + grpinfo = getgrnam("users"); + if(grpinfo == NULL) { + mc_error("getgrnam(users) returns NULL !"); + return NULL; + } + } + else + { + struct passwd *userinfo = getpwuid(uid); + if(userinfo == NULL) { + mc_error("getpwuid(%d) returns NULL !", uid); + return NULL; + } + grpinfo = getgrnam("users"); + if(grpinfo == NULL) { + mc_error("getgrnam(users) returns NULL !"); + return NULL; + } + // Compare git_t type and not group name + if (grpinfo->gr_gid != userinfo->pw_gid) { + mc_error("UID [%d] does not belong to 'users' group!", uid); + return NULL; + } + snprintf(result_psswd, sizeof(result_psswd), "%s/.applications/dbspace/.media_controller.db", userinfo->pw_dir); + } + + dir = strrchr(result_psswd, '/'); + if(!dir) + return strdup(result_psswd); + + //Control if db exist create otherwise + if(access(dir + 1, F_OK)) { + int ret; + mkdir(dir + 1, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH); + ret = chown(dir + 1, uid, grpinfo->gr_gid); + if (ret == -1) { + mc_debug("FAIL : chown %s %d.%d ", dir + 1, uid, grpinfo->gr_gid); + mc_stderror("FAIL : chown"); + } + } + + result_psswd_rtn = strdup(result_psswd); + + return result_psswd_rtn; +} + int mc_db_connect(void **handle) { int ret = MEDIA_CONTROLLER_ERROR_NONE; @@ -176,7 +244,7 @@ int mc_db_connect(void **handle) mc_retvm_if(handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); /*Connect DB*/ - ret = db_util_open(MC_DB_NAME, &db_handle, DB_UTIL_REGISTER_HOOK_METHOD); + ret = db_util_open(__mc_get_db_name(tzplatform_getuid(TZ_USER_NAME)), &db_handle, DB_UTIL_REGISTER_HOOK_METHOD); if (SQLITE_OK != ret) { mc_error("error when db open"); *handle = NULL; diff --git a/src/media_controller_ipc.c b/src/media_controller_ipc.c index 6343a1e..b0d6f45 100755 --- a/src/media_controller_ipc.c +++ b/src/media_controller_ipc.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#include + #include "media_controller_private.h" #define MAX_RETRY_COUNT 3 @@ -290,6 +292,7 @@ int mc_ipc_send_message_to_server(mc_msg_type_e msg_type, const char *request_ms memset((void *)&send_msg, 0, sizeof(mc_comm_msg_s)); send_msg.msg_type = msg_type; + send_msg.uid = tzplatform_getuid(TZ_USER_NAME); send_msg.msg_size = request_msg_size; strncpy(send_msg.msg, request_msg, sizeof(send_msg.msg) - 1); diff --git a/svc/media_controller_db_util.c b/svc/media_controller_db_util.c index faf0c61..2e1eb7f 100755 --- a/svc/media_controller_db_util.c +++ b/svc/media_controller_db_util.c @@ -13,9 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include +#include +#include +#include +#include +#include -#include "media_controller_db_util.h" #include "media_controller_private.h" +#include "media_controller_db_util.h" + +#define FAT_FILEPATH_LEN_MAX 4096 /* inc null */ +#define MC_FILE_PATH_LEN_MAX FAT_FILEPATH_LEN_MAX /**< File path max length (include file name) on file system */ static int __mc_db_util_busy_handler(void *pData, int count) { @@ -26,7 +36,64 @@ static int __mc_db_util_busy_handler(void *pData, int count) return 100 - count; } -int mc_db_util_connect(void **handle) +static char* __mc_get_db_name(uid_t uid) +{ + char result_psswd[MC_FILE_PATH_LEN_MAX]; + char *result_psswd_rtn = NULL; + struct group *grpinfo = NULL; + char * dir = NULL; + + memset(result_psswd, 0, sizeof(result_psswd)); + if(uid == getuid()) + { + strncpy(result_psswd, MC_DB_NAME, sizeof(result_psswd)); + grpinfo = getgrnam("users"); + if(grpinfo == NULL) { + mc_error("getgrnam(users) returns NULL !"); + return NULL; + } + } + else + { + struct passwd *userinfo = getpwuid(uid); + if(userinfo == NULL) { + mc_error("getpwuid(%d) returns NULL !", uid); + return NULL; + } + grpinfo = getgrnam("users"); + if(grpinfo == NULL) { + mc_error("getgrnam(users) returns NULL !"); + return NULL; + } + // Compare git_t type and not group name + if (grpinfo->gr_gid != userinfo->pw_gid) { + mc_error("UID [%d] does not belong to 'users' group!", uid); + return NULL; + } + snprintf(result_psswd, sizeof(result_psswd), "%s/.applications/dbspace/.media_controller.db", userinfo->pw_dir); + } + + dir = strrchr(result_psswd, '/'); + if(!dir) + return strdup(result_psswd); + + //Control if db exist create otherwise + if(access(dir + 1, F_OK)) { + int ret; + mkdir(dir + 1, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH); + ret = chown(dir + 1, uid, grpinfo->gr_gid); + if (ret == -1) { + mc_debug("FAIL : chown %s %d.%d ", dir + 1, uid, grpinfo->gr_gid); + mc_stderror("FAIL : chown"); + } + } + + result_psswd_rtn = strdup(result_psswd); + + return result_psswd_rtn; +} + +int mc_db_util_connect(void **handle, uid_t uid) { int ret = MEDIA_CONTROLLER_ERROR_NONE; sqlite3 *db_handle = NULL; @@ -34,7 +101,7 @@ int mc_db_util_connect(void **handle) mc_retvm_if(handle == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); /*Connect DB*/ - ret = db_util_open(MC_DB_NAME, &db_handle, DB_UTIL_REGISTER_HOOK_METHOD); + ret = db_util_open(__mc_get_db_name(uid), &db_handle, DB_UTIL_REGISTER_HOOK_METHOD); if (SQLITE_OK != ret) { mc_error("error when db open"); *handle = NULL; @@ -100,4 +167,3 @@ int mc_db_util_disconnect(void *handle) return MEDIA_CONTROLLER_ERROR_NONE; } - diff --git a/svc/media_controller_db_util.h b/svc/media_controller_db_util.h index f858a17..4f602fb 100755 --- a/svc/media_controller_db_util.h +++ b/svc/media_controller_db_util.h @@ -21,12 +21,12 @@ #include #include -#define MC_DB_NAME tzplatform_mkpath(TZ_SYS_DB, ".media_controller.db") +#define MC_DB_NAME ".media_controller.db" #define SQLITE3_SAFE_FREE(sql_string) {if(sql_string) { sqlite3_free(sql_string); sql_string = NULL;}} #define SQLITE3_FINALIZE(x) {if(x != NULL) {sqlite3_finalize(x);}} -int mc_db_util_connect(void **handle); +int mc_db_util_connect(void **handle, uid_t uid); int mc_db_util_update_db(void *handle, const char *sql_str); int mc_db_util_disconnect(void *handle); diff --git a/svc/media_controller_socket.c b/svc/media_controller_socket.c index a5b0b3f..a7407d7 100755 --- a/svc/media_controller_socket.c +++ b/svc/media_controller_socket.c @@ -118,10 +118,8 @@ int mc_ipc_create_server_socket(mc_msg_port_type_e port, int *sock_fd) mc_debug("Listening..."); /*change permission of sock file*/ - if (chmod(MC_IPC_PATH, 0660) < 0) + if (chmod(MC_IPC_PATH, 0666) < 0) mc_stderror("chmod failed"); - if (chown(MC_IPC_PATH, 200, 5000) < 0) - mc_stderror("chown failed"); *sock_fd = sock; diff --git a/svc/media_controller_socket.h b/svc/media_controller_socket.h index a17a073..15d5bb9 100755 --- a/svc/media_controller_socket.h +++ b/svc/media_controller_socket.h @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -29,8 +30,8 @@ extern "C" { #define MC_TIMEOUT_SEC_10 10 /**< Response from Server time out */ #define MAX_MSG_SIZE 4096*2 #define MC_SOCK_NOT_ALLOCATE -1 -#define MC_SOCK_ACTIVATION_PATH "/var/run/mediacontroller/media_sa_controller" -#define MC_IPC_PATH "/var/run/mediacontroller/media_ipc_controller" +#define MC_SOCK_ACTIVATION_PATH "/var/run/media-controller/media_sa_controller" +#define MC_IPC_PATH "/var/run/media-controller/media_ipc_controller" #define MC_SERVER_CONNECTION_MSG "Connect" #define MC_SERVER_DISCONNECTION_MSG "Disonnect" @@ -56,6 +57,7 @@ typedef struct { typedef struct { mc_msg_type_e msg_type; int pid; + uid_t uid; int result; size_t msg_size; /*this is size of message below and this does not include the terminationg null byte ('\0'). */ char msg[MAX_MSG_SIZE]; diff --git a/svc/media_controller_svc.c b/svc/media_controller_svc.c index 55e4905..79bbee8 100755 --- a/svc/media_controller_svc.c +++ b/svc/media_controller_svc.c @@ -92,6 +92,11 @@ gboolean _mc_read_service_request_tcp_socket(GIOChannel *src, GIOCondition condi } if (recv_msg.msg_type == MC_MSG_DB_UPDATE) { + /* Connect media controller DB*/ + if(mc_db_util_connect(&(mc_svc_data->db_handle), recv_msg.uid) != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Failed to connect DB"); + goto ERROR; + } sql_query = strndup(recv_msg.msg, recv_msg.msg_size); if (sql_query != NULL) { ret = mc_db_util_update_db(mc_svc_data->db_handle, sql_query); @@ -103,6 +108,10 @@ gboolean _mc_read_service_request_tcp_socket(GIOChannel *src, GIOCondition condi } else { send_msg = MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; } + /* Disconnect DB*/ + if(mc_db_util_disconnect(mc_svc_data->db_handle) != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Failed to disconnect DB"); + } } else if (recv_msg.msg_type == MC_MSG_CLIENT_SET) { /* check privileage */ ret = __mc_privilege_ask(client_sock, "mediacontroller::svc", "w"); @@ -220,13 +229,6 @@ gboolean mc_svc_thread(void *data) return FALSE; } - /* Connect Media DB*/ - if (mc_db_util_connect(&(mc_svc_data->db_handle)) != MEDIA_CONTROLLER_ERROR_NONE) { - mc_error("Failed to connect DB"); - close(sockfd); - return FALSE; - } - /* Create list for command*/ mc_svc_data->mc_svc_list = g_list_alloc(); if (mc_svc_data->mc_svc_list == NULL) { @@ -266,8 +268,6 @@ gboolean mc_svc_thread(void *data) g_io_channel_shutdown(channel, FALSE, NULL); g_io_channel_unref(channel); - /* Disconnect DB*/ - mc_db_util_disconnect(mc_svc_data->db_handle); if (mc_svc_data->mc_svc_list != NULL) { int i = 0; diff --git a/test/server_test/media_controller_server_test.c b/test/server_test/media_controller_server_test.c index 941d405..2b2693d 100755 --- a/test/server_test/media_controller_server_test.c +++ b/test/server_test/media_controller_server_test.c @@ -13,82 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#if 0 -#include -#include -#include - -#define PACKAGE "MC_SERVER_TEST" - -/*=========================================================================================== -| | -| LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE | -| | -========================================================================================== */ -/*--------------------------------------------------------------------------- -| GLOBAL VARIABLE DEFINITIONS: | ----------------------------------------------------------------------------*/ - -GMainLoop *g_loop; - -/*--------------------------------------------------------------------------- -| LOCAL CONSTANT DEFINITIONS: | ----------------------------------------------------------------------------*/ - -/*--------------------------------------------------------------------------- -| LOCAL VARIABLE DEFINITIONS: | ----------------------------------------------------------------------------*/ - -static unsigned long long duration = 0; -/*--------------------------------------------------------------------------- -| LOCAL FUNCTION PROTOTYPES: | ----------------------------------------------------------------------------*/ - -void quit_program(void *mc_server) -{ - mc_server_destroy(mc_server); - mc_server = NULL; - g_main_loop_quit(g_loop); -} -static gboolean __func1(void *mc_server) -{ - int i = MEDIA_TITLE; - - mc_server_set_playback_state(mc_server, MEDIA_PLAYBACK_STATE_PLAYING); - mc_server_set_playback_position(mc_server, duration); - mc_server_update_playback_info(mc_server); - - for (; i <= MEDIA_PICTURE; ++i) { - mc_server_set_metadata(mc_server, (mc_meta_e)i, "META_VALUE"); - } - mc_server_update_metadata(mc_server); - mc_server_update_shuffle_mode(mc_server, SHUFFLE_MODE_OFF); - mc_server_update_repeat_mode(mc_server, REPEAT_MODE_OFF); - g_usleep(4000); - duration += 4000; - return TRUE; -} - -int main(int argc, char *argv[]) -{ - mc_server_h mc_server = NULL; - int error = MEDIA_CONTROLLER_ERROR_NONE; - - error = mc_server_create(&mc_server); - if (MEDIA_CONTROLLER_ERROR_NONE == error && mc_server != NULL) { - g_timeout_add_seconds(5, __func1, (void *)mc_server); - - g_loop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(g_loop); - quit_program(mc_server); - } else { - dlog_print(DLOG_INFO, PACKAGE, "mc_server_create: error %d ", error); - } - - return error; -} -#else #include #include #include @@ -627,5 +552,3 @@ int main(int argc, char **argv) return 0; } - -#endif