2 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Bumjin Im <bj.im@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
19 * @file get-object-name.cpp
20 * @author Jan Olszak (j.olszak@samsung.com)
22 * @brief Implementation of api-get-object-name service.
25 #include <sys/smack.h>
28 #include <dpl/log/log.h>
29 #include <dpl/serialization.h>
31 #include <protocols.h>
32 #include <get-object-name.h>
33 #include <security-server.h>
37 namespace SecurityServer {
39 GetObjectNameService::ServiceDescriptionVector GetObjectNameService::GetServiceDescription() {
40 ServiceDescription sd = {
43 SERVICE_SOCKET_GET_OBJECT_NAME
45 ServiceDescriptionVector v;
50 void GetObjectNameService::accept(const AcceptEvent &event) {
51 LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
52 << " ConnectionID.counter: " << event.connectionID.counter
53 << " ServiceID: " << event.interfaceID);
56 void GetObjectNameService::write(const WriteEvent &event) {
57 LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
58 " Size: " << event.size << " Left: " << event.left);
60 m_serviceManager->Close(event.connectionID);
66 * Searches for group NAME by given group id
68 int GetObjectNameService::setName(const gid_t gid)
71 struct group *grpbuf = NULL;
73 std::vector<char> buf;
76 * The maximum needed size for buf can be found using sysconf(3)
77 * with the argument _SC_GETGR_R_SIZE_MAX. If _SC_GETGR_R_SIZE_MAX is not
78 * returned we set max_buf_size to 1024 bytes. Enough to store few groups.
80 long int maxBufSize = sysconf(_SC_GETGR_R_SIZE_MAX);
86 * There can be some corner cases when for example user is assigned to a
87 * lot of groups. In that case if buffer is to small getgrnam_r will
88 * return ERANGE error. Solution could be calling getgrnam_r with bigger
89 * buffer until it's big enough.
93 buf.resize(maxBufSize);
94 }catch(std::bad_alloc&) {
95 ret = SECURITY_SERVER_API_ERROR_OUT_OF_MEMORY;
96 LogError("Out Of Memory");
101 } while ((ret = getgrgid_r(gid, &grp, &(buf[0]), buf.size(), &grpbuf)) == ERANGE);
105 ret = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
106 LogError("getgrgid_r failed with error: " << strerror(errno));
109 } else if (grpbuf == NULL) {
110 ret = SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT;
111 LogError("Cannot find name for group: " << gid);
115 m_name = grpbuf->gr_name;
121 bool GetObjectNameService::readOne(const ConnectionID &conn, SocketBuffer &buffer) {
122 LogDebug("Iteration begin");
124 int retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
125 if (!buffer.Ready()) {
126 LogDebug("Got part of message. Service is waiting for the rest.");
132 SecurityServer::Deserialization des;
133 des.Deserialize(buffer, gid);
134 } Catch (SocketBuffer::Exception::Base) {
135 LogDebug("Broken protocol. Closing socket.");
136 m_serviceManager->Close(conn);
141 retCode = setName(gid);
144 SecurityServer::Serialization ser;
145 SocketBuffer sendBuffer;
146 ser.Serialize(sendBuffer, retCode);
147 ser.Serialize(sendBuffer, m_name);
148 m_serviceManager->Write(conn, sendBuffer.Pop());
152 void GetObjectNameService::read(const ReadEvent &event) {
153 LogDebug("Read event for counter: " << event.connectionID.counter);
154 auto &buffer = m_socketBufferMap[event.connectionID.counter];
155 buffer.Push(event.rawBuffer);
157 LogDebug("Pushed to buffer ptr: " << (void*)&buffer);
159 // We can get several requests in one package.
160 // Extract and process them all
161 while(readOne(event.connectionID, buffer));
164 void GetObjectNameService::close(const CloseEvent &event) {
165 LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
166 m_socketBufferMap.erase(event.connectionID.counter);
169 void GetObjectNameService::error(const ErrorEvent &event) {
170 LogError("ErrorEvent. ConnectionID: " << event.connectionID.sock);
171 m_serviceManager->Close(event.connectionID);
174 } // namespace SecurityServer