Implemented security_server_get_object_name function in new framework.
authorJan Olszak <j.olszak@samsung.com>
Tue, 9 Jul 2013 10:03:56 +0000 (12:03 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 6 Feb 2014 16:13:21 +0000 (17:13 +0100)
[Issue#] Function for new security-server framework.
[Bug/Feature] Get name in new security-server.
[Cause] N/A
[Solution] Reimplemented solution.
[Verification]  Build, install, run tests.

Change-Id: I432170b517f4a3ee20d2db4281e18f7bd7dd449d

src/CMakeLists.txt
src/client/security-server-client.c
src/communication/security-server-comm.c
src/include/security-server-comm.h
src/server/security-server-main.c
src/server2/client/client-get-object-name.cpp [new file with mode: 0644]
src/server2/common/protocols.cpp
src/server2/common/protocols.h
src/server2/main/server2-main.cpp
src/server2/service/get-object-name.cpp [new file with mode: 0644]
src/server2/service/get-object-name.h [new file with mode: 0644]

index 297c245..dc87653 100644 (file)
@@ -24,6 +24,7 @@ SET(SECURITY_SERVER_SOURCES
     ${SERVER2_PATH}/service/get-gid.cpp
     ${SERVER2_PATH}/service/privilege-by-pid.cpp
     ${SERVER2_PATH}/service/exec-path.cpp
+    ${SERVER2_PATH}/service/get-object-name.cpp
     )
 
 SET_SOURCE_FILES_PROPERTIES(
@@ -67,6 +68,7 @@ SET(SECURITY_CLIENT_SOURCES
     ${SECURITY_SERVER_PATH}/server2/client/client-get-gid.cpp
     ${SECURITY_SERVER_PATH}/server2/client/client-privilege-by-pid.cpp
     ${SECURITY_SERVER_PATH}/server2/client/client-socket-privilege.cpp
+    ${SECURITY_SERVER_PATH}/server2/client/client-get-object-name.cpp
     ${SECURITY_SERVER_PATH}/client/security-server-client.c
     ${SECURITY_SERVER_PATH}/communication/security-server-comm.c
     ${SECURITY_SERVER_PATH}/util/smack-check.c
index 8d35de0..927254b 100644 (file)
@@ -191,66 +191,68 @@ int convert_to_public_error_code(int err_code)
 //     return retval;
 // }
 
-SECURITY_SERVER_API
-int security_server_get_object_name(gid_t gid, char *object, size_t max_object_size)
-{
-    int sockfd = -1, retval;
-    response_header hdr;
 
-    if (object == NULL)
-    {
-        retval = SECURITY_SERVER_ERROR_INPUT_PARAM;
-        goto error;
-    }
 
-    retval = connect_to_server(&sockfd);
-    if (retval != SECURITY_SERVER_SUCCESS)
-    {
-        /* Error on socket */
-        SEC_SVR_ERR("Client: connect to server failed: %d", retval);
-        goto error;
-    }
+// SECURITY_SERVER_API
+// int security_server_get_object_name(gid_t gid, char *object, size_t max_object_size)
+// {
+//     int sockfd = -1, retval;
+//     response_header hdr;
 
-    /* make request packet */
-    retval = send_object_name_request(sockfd, gid);
-    if (retval != SECURITY_SERVER_SUCCESS)
-    {
-        /* Error on socket */
-        SEC_SVR_ERR("Client: cannot send request: %d", retval);
-        goto error;
-    }
+//     if (object == NULL)
+//     {
+//         retval = SECURITY_SERVER_ERROR_INPUT_PARAM;
+//         goto error;
+//     }
 
-    retval = recv_get_object_name(sockfd, &hdr, object, max_object_size);
-    if (retval != SECURITY_SERVER_SUCCESS)
-    {
-        SEC_SVR_ERR("Client: Receive response failed: %d", retval);
-        goto error;
-    }
+//     retval = connect_to_server(&sockfd);
+//     if (retval != SECURITY_SERVER_SUCCESS)
+//     {
+//         /* Error on socket */
+//         SEC_SVR_ERR("Client: connect to server failed: %d", retval);
+//         goto error;
+//     }
 
-    if (hdr.basic_hdr.msg_id != SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE)   /* Wrong response */
-    {
-        if (hdr.basic_hdr.msg_id == SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE)
-        {
-            /* There must be some error */
-            SEC_SVR_ERR("Client: There is error on response: return code:%d", hdr.basic_hdr.msg_id);
-            retval = return_code_to_error_code(hdr.return_code);
-        }
-        else
-        {
-            /* Something wrong with response */
-            SEC_SVR_ERR("Client: Some unexpected error happene: return code:%d", hdr.basic_hdr.msg_id);
-            retval = SECURITY_SERVER_ERROR_BAD_RESPONSE;
-        }
-        goto error;
-    }
+//     /* make request packet */
+//     retval = send_object_name_request(sockfd, gid);
+//     if (retval != SECURITY_SERVER_SUCCESS)
+//     {
+//         /* Error on socket */
+//         SEC_SVR_ERR("Client: cannot send request: %d", retval);
+//         goto error;
+//     }
 
-error:
-    if (sockfd > 0)
-        close(sockfd);
+//     retval = recv_get_object_name(sockfd, &hdr, object, max_object_size);
+//     if (retval != SECURITY_SERVER_SUCCESS)
+//     {
+//         SEC_SVR_ERR("Client: Receive response failed: %d", retval);
+//         goto error;
+//     }
 
-    retval = convert_to_public_error_code(retval);
-    return retval;
-}
+//     if (hdr.basic_hdr.msg_id != SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE)   /* Wrong response */
+//     {
+//         if (hdr.basic_hdr.msg_id == SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE)
+//         {
+//             /* There must be some error */
+//             SEC_SVR_ERR("Client: There is error on response: return code:%d", hdr.basic_hdr.msg_id);
+//             retval = return_code_to_error_code(hdr.return_code);
+//         }
+//         else
+//         {
+//             /* Something wrong with response */
+//             SEC_SVR_ERR("Client: Some unexpected error happene: return code:%d", hdr.basic_hdr.msg_id);
+//             retval = SECURITY_SERVER_ERROR_BAD_RESPONSE;
+//         }
+//         goto error;
+//     }
+
+// error:
+//     if (sockfd > 0)
+//         close(sockfd);
+
+//     retval = convert_to_public_error_code(retval);
+//     return retval;
+// }
 
 
 
index 855ba2f..2039f14 100644 (file)
@@ -958,43 +958,43 @@ error:
  * |                               gid                             |
  * |---------------------------------------------------------------|
  */
-int send_object_name_request(int sock_fd, int gid)
-{
-    basic_header hdr;
-    int retval;
-    unsigned char buf[sizeof(hdr) + sizeof(gid)];
-
-    /* Assemble header */
-    hdr.version = SECURITY_SERVER_MSG_VERSION;
-    hdr.msg_id = SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_REQUEST;
-    hdr.msg_len = sizeof(gid);
-
-    memcpy(buf, &hdr, sizeof(hdr));
-    memcpy(buf + sizeof(hdr), &gid, sizeof(gid));
-
-    /* Check poll */
-    retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
-    if (retval == SECURITY_SERVER_ERROR_POLL)
-    {
-        SEC_SVR_ERR("%s", "poll() error");
-        return SECURITY_SERVER_ERROR_SEND_FAILED;
-    }
-    if (retval == SECURITY_SERVER_ERROR_TIMEOUT)
-    {
-        SEC_SVR_ERR("%s", "poll() timeout");
-        return SECURITY_SERVER_ERROR_SEND_FAILED;
-    }
-
-    /* Send to server */
-    retval = TEMP_FAILURE_RETRY(write(sock_fd, buf, sizeof(buf)));
-    if (retval < sizeof(buf))
-    {
-        /* Write error */
-        SEC_SVR_ERR("Error on write(): %d", retval);
-        return SECURITY_SERVER_ERROR_SEND_FAILED;
-    }
-    return SECURITY_SERVER_SUCCESS;
-}
+// int send_object_name_request(int sock_fd, int gid)
+// {
+//     basic_header hdr;
+//     int retval;
+//     unsigned char buf[sizeof(hdr) + sizeof(gid)];
+
+//     /* Assemble header */
+//     hdr.version = SECURITY_SERVER_MSG_VERSION;
+//     hdr.msg_id = SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_REQUEST;
+//     hdr.msg_len = sizeof(gid);
+
+//     memcpy(buf, &hdr, sizeof(hdr));
+//     memcpy(buf + sizeof(hdr), &gid, sizeof(gid));
+
+//     /* Check poll */
+//     retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
+//     if (retval == SECURITY_SERVER_ERROR_POLL)
+//     {
+//         SEC_SVR_ERR("%s", "poll() error");
+//         return SECURITY_SERVER_ERROR_SEND_FAILED;
+//     }
+//     if (retval == SECURITY_SERVER_ERROR_TIMEOUT)
+//     {
+//         SEC_SVR_ERR("%s", "poll() timeout");
+//         return SECURITY_SERVER_ERROR_SEND_FAILED;
+//     }
+
+//     /* Send to server */
+//     retval = TEMP_FAILURE_RETRY(write(sock_fd, buf, sizeof(buf)));
+//     if (retval < sizeof(buf))
+//     {
+//         /* Write error */
+//         SEC_SVR_ERR("Error on write(): %d", retval);
+//         return SECURITY_SERVER_ERROR_SEND_FAILED;
+//     }
+//     return SECURITY_SERVER_SUCCESS;
+// }
 
 /* Send privilege check request message to security server *
  *
index 8bf4a10..0813462 100644 (file)
@@ -43,8 +43,8 @@ typedef struct
 #define SECURITY_SERVER_MSG_TYPE_COOKIE_RESPONSE                0x02
 #define SECURITY_SERVER_MSG_TYPE_CHECK_PRIVILEGE_REQUEST        0x03
 #define SECURITY_SERVER_MSG_TYPE_CHECK_PRIVILEGE_RESPONSE       0x04
-#define SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_REQUEST            0x05
-#define SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE           0x06
+// #define SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_REQUEST            0x05
+// #define SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE           0x06
 #define SECURITY_SERVER_MSG_TYPE_GID_REQUEST                    0x07
 #define SECURITY_SERVER_MSG_TYPE_GID_RESPONSE                   0x08
 #define SECURITY_SERVER_MSG_TYPE_PID_REQUEST                    0x09
index 0b615c1..e4726d0 100644 (file)
@@ -619,82 +619,82 @@ error:
     return retval;
 }
 
-int process_object_name_request(int sockfd)
-{
-    int retval, client_pid, requested_privilege;
-    char object_name[SECURITY_SERVER_MAX_OBJ_NAME];
-
-    /* Authenticate client */
-    retval = authenticate_client_middleware(sockfd, &client_pid);
-    if (retval != SECURITY_SERVER_SUCCESS)
-    {
-        SEC_SVR_ERR("%s", "Client Authentication Failed");
-        retval = send_generic_response(sockfd,
-            SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE,
-            SECURITY_SERVER_RETURN_CODE_AUTHENTICATION_FAILED);
-        if (retval != SECURITY_SERVER_SUCCESS)
-        {
-            SEC_SVR_ERR("ERROR: Cannot send generic response: %d", retval);
-        }
-        goto error;
-    }
-
-    /* Receive GID */
-    retval = TEMP_FAILURE_RETRY(read(sockfd, &requested_privilege, sizeof(requested_privilege)));
-    if (retval < (int)sizeof(requested_privilege))
-    {
-        SEC_SVR_ERR("%s", "Receiving request failed");
-        retval = send_generic_response(sockfd,
-            SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE,
-            SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
-        if (retval != SECURITY_SERVER_SUCCESS)
-        {
-            SEC_SVR_ERR("ERROR: Cannot send generic response: %d", retval);
-        }
-        goto error;
-    }
-
-    /* Search from /etc/group */
-    retval = search_object_name(requested_privilege,
-        object_name,
-        SECURITY_SERVER_MAX_OBJ_NAME);
-    if (retval == SECURITY_SERVER_ERROR_NO_SUCH_OBJECT)
-    {
-        /* It's not exist */
-        SEC_SVR_ERR("There is no such object for gid [%d]", requested_privilege);
-        retval = send_generic_response(sockfd,
-            SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE,
-            SECURITY_SERVER_RETURN_CODE_NO_SUCH_OBJECT);
-        if (retval != SECURITY_SERVER_SUCCESS)
-        {
-            SEC_SVR_ERR("ERROR: Cannot send generic response: %d", retval);
-        }
-        goto error;
-    }
-    if (retval != SECURITY_SERVER_SUCCESS)
-    {
-        /* Error occurred */
-        SEC_SVR_ERR("Error on searching object name [%d]", retval);
-        retval = send_generic_response(sockfd,
-            SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE,
-            SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
-        if (retval != SECURITY_SERVER_SUCCESS)
-        {
-            SEC_SVR_ERR("ERROR: Cannot send generic response: %d", retval);
-        }
-        goto error;
-    }
-
-    /* We found */
-    SECURE_SLOGD("We found object: %s", object_name);
-    retval = send_object_name(sockfd, object_name);
-    if (retval != SECURITY_SERVER_SUCCESS)
-    {
-        SEC_SVR_ERR("ERROR: Cannot send generic response: %d", retval);
-    }
-error:
-    return retval;
-}
+// int process_object_name_request(int sockfd)
+// {
+//     int retval, client_pid, requested_privilege;
+//     char object_name[SECURITY_SERVER_MAX_OBJ_NAME];
+
+//     /* Authenticate client */
+//     retval = authenticate_client_middleware(sockfd, &client_pid);
+//     if (retval != SECURITY_SERVER_SUCCESS)
+//     {
+//         SEC_SVR_ERR("%s", "Client Authentication Failed");
+//         retval = send_generic_response(sockfd,
+//             SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE,
+//             SECURITY_SERVER_RETURN_CODE_AUTHENTICATION_FAILED);
+//         if (retval != SECURITY_SERVER_SUCCESS)
+//         {
+//             SEC_SVR_ERR("ERROR: Cannot send generic response: %d", retval);
+//         }
+//         goto error;
+//     }
+
+//     /* Receive GID */
+//     retval = TEMP_FAILURE_RETRY(read(sockfd, &requested_privilege, sizeof(requested_privilege)));
+//     if (retval < (int)sizeof(requested_privilege))
+//     {
+//         SEC_SVR_ERR("%s", "Receiving request failed");
+//         retval = send_generic_response(sockfd,
+//             SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE,
+//             SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
+//         if (retval != SECURITY_SERVER_SUCCESS)
+//         {
+//             SEC_SVR_ERR("ERROR: Cannot send generic response: %d", retval);
+//         }
+//         goto error;
+//     }
+
+//     /* Search from /etc/group */
+//     retval = search_object_name(requested_privilege,
+//         object_name,
+//         SECURITY_SERVER_MAX_OBJ_NAME);
+//     if (retval == SECURITY_SERVER_ERROR_NO_SUCH_OBJECT)
+//     {
+//         /* It's not exist */
+//         SEC_SVR_ERR("There is no such object for gid [%d]", requested_privilege);
+//         retval = send_generic_response(sockfd,
+//             SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE,
+//             SECURITY_SERVER_RETURN_CODE_NO_SUCH_OBJECT);
+//         if (retval != SECURITY_SERVER_SUCCESS)
+//         {
+//             SEC_SVR_ERR("ERROR: Cannot send generic response: %d", retval);
+//         }
+//         goto error;
+//     }
+//     if (retval != SECURITY_SERVER_SUCCESS)
+//     {
+//         /* Error occurred */
+//         SEC_SVR_ERR("Error on searching object name [%d]", retval);
+//         retval = send_generic_response(sockfd,
+//             SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_RESPONSE,
+//             SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
+//         if (retval != SECURITY_SERVER_SUCCESS)
+//         {
+//             SEC_SVR_ERR("ERROR: Cannot send generic response: %d", retval);
+//         }
+//         goto error;
+//     }
+
+//     /* We found */
+//     SECURE_SLOGD("We found object: %s", object_name);
+//     retval = send_object_name(sockfd, object_name);
+//     if (retval != SECURITY_SERVER_SUCCESS)
+//     {
+//         SEC_SVR_ERR("ERROR: Cannot send generic response: %d", retval);
+//     }
+// error:
+//     return retval;
+// }
 
 int process_gid_request(int sockfd, int msg_len)
 {
@@ -1254,11 +1254,11 @@ void *security_server_thread(void *param)
             process_check_privilege_new_request(client_sockfd);
             break;
 
-        case SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_REQUEST:
-            SECURE_SLOGD("%s", "Get object name request received");
-            authorize_SS_API_caller_socket(client_sockfd, API_MIDDLEWARE, API_RULE_REQUIRED);
-            process_object_name_request(client_sockfd);
-            break;
+        // case SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_REQUEST:
+        //     SECURE_SLOGD("%s", "Get object name request received");
+        //     authorize_SS_API_caller_socket(client_sockfd, API_MIDDLEWARE, API_RULE_REQUIRED);
+        //     process_object_name_request(client_sockfd);
+        //     break;
 
         case SECURITY_SERVER_MSG_TYPE_GID_REQUEST:
             SEC_SVR_DBG("%s", "Get GID received");
diff --git a/src/server2/client/client-get-object-name.cpp b/src/server2/client/client-get-object-name.cpp
new file mode 100644 (file)
index 0000000..da83ac0
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        client-get-object-name.cpp
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     1.0
+ * @brief       This file constains implementation of get NAME function.
+ */
+
+#include <stdio.h>
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <socket-buffer.h>
+#include <client-common.h>
+#include <protocols.h>
+
+#include <security-server.h>
+#include <security-server-common.h>
+
+SECURITY_SERVER_API
+int security_server_get_object_name(gid_t gid, char *pObjectName, size_t maxObjectSize)
+ {
+    using namespace SecurityServer;
+    try {
+        if (pObjectName == NULL){
+            LogDebug("Objects name is NULL or empty");
+            return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+        }
+
+        SocketBuffer send, recv;
+        Serialization ser;
+        ser.Serialize(send, gid);
+
+        int result = sendToServer(
+          SERVICE_SOCKET_GET_OBJECT_NAME,
+          send.Pop(),
+          recv);
+
+
+        if (result != SECURITY_SERVER_API_SUCCESS)
+            return result;
+
+        Deserialization des;
+        des.Deserialize(recv, result);
+
+        std::string retObjectName;
+        des.Deserialize(recv, retObjectName);
+
+        if(retObjectName.size() > maxObjectSize){
+            LogError("Objects name is too big. Need more space in pObjectName buffer.");
+            return SECURITY_SERVER_API_ERROR_BUFFER_TOO_SMALL;
+        }
+
+        strcpy(pObjectName,retObjectName.c_str());
+
+        return result;
+
+    } catch (SocketBuffer::Exception::Base &e) {
+        LogDebug("SecurityServer::SocketBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogDebug("STD exception " << e.what());
+    } catch (...) {
+        LogDebug("Unknown exception occured");
+    }
+    return SECURITY_SERVER_API_ERROR_UNKNOWN;
+}
+
index dc579f1..347d4c6 100644 (file)
@@ -36,6 +36,8 @@ char const * const SERVICE_SOCKET_PRIVILEGE_BY_PID =
     "/tmp/.security-server-api-privilege-by-pid";
 char const * const SERVICE_SOCKET_EXEC_PATH =
     "/tmp/.security-server-api-exec-path.sock";
+char const * const SERVICE_SOCKET_GET_OBJECT_NAME =
+    "/tmp/.security-server-api-get-object-name.sock";
 
 } // namespace SecurityServer
 
index 3ed74d7..4152383 100644 (file)
@@ -32,6 +32,7 @@ extern char const * const SERVICE_SOCKET_ECHO;
 extern char const * const SERVICE_SOCKET_GET_GID;
 extern char const * const SERVICE_SOCKET_PRIVILEGE_BY_PID;
 extern char const * const SERVICE_SOCKET_EXEC_PATH;
+extern char const * const SERVICE_SOCKET_GET_OBJECT_NAME;
 
 } // namespace SecuritySever
 
index 289ac76..291f323 100644 (file)
@@ -35,6 +35,7 @@
 #include <get-gid.h>
 #include <privilege-by-pid.h>
 #include <exec-path.h>
+#include <get-object-name.h>
 #include <echo.h>
 
 IMPLEMENT_SAFE_SINGLETON(SecurityServer::Log::LogSystem);
@@ -67,6 +68,10 @@ int server2(void) {
         execService->Create();
         manager.RegisterSocketService(execService);
 
+        SecurityServer::GetObjectNameService *getObjectNameService = new SecurityServer::GetObjectNameService;
+        getObjectNameService->Create();
+        manager.RegisterSocketService(getObjectNameService);
+
         manager.MainLoop();
     }
     UNHANDLED_EXCEPTION_HANDLER_END
diff --git a/src/server2/service/get-object-name.cpp b/src/server2/service/get-object-name.cpp
new file mode 100644 (file)
index 0000000..fdcb2fc
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        get-object-name.cpp
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of api-get-object-name service.
+ */
+
+#include <sys/smack.h>
+#include <grp.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <protocols.h>
+#include <get-object-name.h>
+#include <security-server.h>
+
+#include <vector>
+
+namespace SecurityServer {
+
+GetObjectNameService::ServiceDescriptionVector GetObjectNameService::GetServiceDescription() {
+    ServiceDescription sd = {
+        "*",
+        0,
+        SERVICE_SOCKET_GET_OBJECT_NAME
+    };
+    ServiceDescriptionVector v;
+    v.push_back(sd);
+    return v;
+}
+
+void GetObjectNameService::accept(const AcceptEvent &event) {
+    LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
+        << " ConnectionID.counter: " << event.connectionID.counter
+        << " ServiceID: " << event.interfaceID);
+}
+
+void GetObjectNameService::write(const WriteEvent &event) {
+    LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
+        " Size: " << event.size << " Left: " << event.left);
+    if (event.left == 0)
+        m_serviceManager->Close(event.connectionID);
+}
+
+
+
+/*
+ * Searches for group NAME by given group id
+ */
+int GetObjectNameService::setName(const gid_t gid)
+{
+    int ret = 0;
+    struct group *grpbuf = NULL;
+    struct group grp;
+    std::vector<char> buf;
+
+    /*
+     * The maximum needed size for buf can be found using sysconf(3)
+     * with the argument _SC_GETGR_R_SIZE_MAX. If _SC_GETGR_R_SIZE_MAX is not
+     * returned we set max_buf_size to 1024 bytes. Enough to store few groups.
+     */
+    long int maxBufSize = sysconf(_SC_GETGR_R_SIZE_MAX);
+    if (maxBufSize == -1)
+        maxBufSize = 1024;
+
+
+    /*
+     * There can be some corner cases when for example user is assigned to a
+     * lot of groups. In that case if buffer is to small getgrnam_r will
+     * return ERANGE error. Solution could be calling getgrnam_r with bigger
+     * buffer until it's big enough.
+     */
+    do {
+        try{
+            buf.resize(maxBufSize);
+        }catch(std::bad_alloc&) {
+            ret = SECURITY_SERVER_API_ERROR_OUT_OF_MEMORY;
+            LogError("Out Of Memory");
+            return ret;
+        }
+        maxBufSize *= 2;
+
+    } while ((ret = getgrgid_r(gid, &grp, &(buf[0]), buf.size(), &grpbuf)) == ERANGE);
+
+    // Check for errors:
+    if (ret != 0){
+        ret = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+        LogError("getgrgid_r failed with error: " << strerror(errno));
+        return ret;
+
+    } else if (grpbuf == NULL) {
+        ret = SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT;
+        LogError("Cannot find name for group: " << gid);
+        return ret;
+    }
+
+    m_name = grpbuf->gr_name;
+
+    return ret;
+}
+
+
+bool GetObjectNameService::readOne(const ConnectionID &conn, SocketBuffer &buffer) {
+    LogDebug("Iteration begin");
+    gid_t gid;
+    int retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+    if (!buffer.Ready()) {
+        LogDebug("Got part of message. Service is waiting for the rest.");
+        return false;
+    }
+
+    // Get objects GID:
+    Try {
+        SecurityServer::Deserialization des;
+        des.Deserialize(buffer, gid);
+     } Catch (SocketBuffer::Exception::Base) {
+        LogDebug("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }
+
+    // Get name
+    retCode = setName(gid);
+
+    // Send the result
+    SecurityServer::Serialization ser;
+    SocketBuffer sendBuffer;
+    ser.Serialize(sendBuffer, retCode);
+    ser.Serialize(sendBuffer, m_name);
+    m_serviceManager->Write(conn, sendBuffer.Pop());
+    return true;
+}
+
+void GetObjectNameService::read(const ReadEvent &event) {
+    LogDebug("Read event for counter: " << event.connectionID.counter);
+    auto &buffer = m_socketBufferMap[event.connectionID.counter];
+    buffer.Push(event.rawBuffer);
+
+    LogDebug("Pushed to buffer ptr: " << (void*)&buffer);
+
+    // We can get several requests in one package.
+    // Extract and process them all
+    while(readOne(event.connectionID, buffer));
+}
+
+void GetObjectNameService::close(const CloseEvent &event) {
+    LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+    m_socketBufferMap.erase(event.connectionID.counter);
+}
+
+void GetObjectNameService::error(const ErrorEvent &event) {
+    LogError("ErrorEvent. ConnectionID: " << event.connectionID.sock);
+    m_serviceManager->Close(event.connectionID);
+}
+
+} // namespace SecurityServer
+
diff --git a/src/server2/service/get-object-name.h b/src/server2/service/get-object-name.h
new file mode 100644 (file)
index 0000000..5083788
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        get-object-name.h
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of api-get-object-name service.
+ */
+
+#ifndef _SECURITY_SERVER_SERV_GET_OBJECT_NAME_
+#define _SECURITY_SERVER_SERV_GET_OBJECT_NAME_
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+
+#include <dpl/serialization.h>
+#include <socket-buffer.h>
+
+#include <security-server-common.h>
+
+namespace SecurityServer {
+
+class GetObjectNameService  :
+    public SecurityServer::GenericSocketService
+  , public SecurityServer::ServiceThread<GetObjectNameService>
+{
+public:
+    typedef std::map<int, SocketBuffer> SocketBufferMap;
+
+    ServiceDescriptionVector GetServiceDescription();
+
+    DECLARE_THREAD_EVENT(AcceptEvent, accept)
+    DECLARE_THREAD_EVENT(WriteEvent, write)
+    DECLARE_THREAD_EVENT(ReadEvent, read)
+    DECLARE_THREAD_EVENT(CloseEvent, close)
+    DECLARE_THREAD_EVENT(ErrorEvent, error)
+
+    void accept(const AcceptEvent &event);
+    void write(const WriteEvent &event);
+    void read(const ReadEvent &event);
+    void close(const CloseEvent &event);
+    void error(const ErrorEvent &event);
+
+private:
+    std::string m_name;
+    bool readOne(const ConnectionID &conn, SocketBuffer &buffer);
+    int  setName(gid_t gid);
+    SocketBufferMap m_socketBufferMap;
+};
+
+} // namespace SecurityServer
+
+#endif // _SECURITY_SERVER_SERV_GET_OBJECT_NAME_
\ No newline at end of file