Added support for SO_PEERCRED for Unix sockets.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25305 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2008-05-04 00:32:57 +00:00
parent b946bc32e2
commit 5d55026291
3 changed files with 44 additions and 4 deletions

View File

@ -254,6 +254,10 @@ UnixEndpoint::Listen(int backlog)
_UnsetReceiveFifo();
fCredentials.pid = getpid();
fCredentials.uid = geteuid();
fCredentials.gid = getegid();
fState = UNIX_ENDPOINT_LISTENING;
RETURN_ERROR(B_OK);
@ -352,7 +356,7 @@ UnixEndpoint::Connect(const struct sockaddr *_address)
UnixEndpointLocker connectedLocker(connectedEndpoint);
connectedEndpoint->_Spawn(this, peerFifo);
connectedEndpoint->_Spawn(this, listeningEndpoint, peerFifo);
// update our attributes
_UnsetReceiveFifo();
@ -362,6 +366,10 @@ UnixEndpoint::Connect(const struct sockaddr *_address)
fPeerEndpoint->AddReference();
fReceiveFifo = fifo;
fCredentials.pid = getpid();
fCredentials.uid = geteuid();
fCredentials.gid = getegid();
fifoDeleter.Detach();
peerFifoDeleter.Detach();
@ -650,6 +658,22 @@ UnixEndpoint::SetReceiveBufferSize(size_t size)
}
status_t
UnixEndpoint::GetPeerCredentials(ucred* credentials)
{
UnixEndpointLocker locker(this);
UnixEndpointLocker peerLocker;
status_t error = _LockConnectedEndpoints(locker, peerLocker);
if (error != B_OK)
RETURN_ERROR(error);
*credentials = fPeerEndpoint->fCredentials;
return B_OK;
}
status_t
UnixEndpoint::Shutdown(int direction)
{
@ -710,7 +734,8 @@ UnixEndpoint::Shutdown(int direction)
void
UnixEndpoint::_Spawn(UnixEndpoint* connectingEndpoint, UnixFifo* fifo)
UnixEndpoint::_Spawn(UnixEndpoint* connectingEndpoint,
UnixEndpoint* listeningEndpoint, UnixFifo* fifo)
{
ProtocolSocket::Open();
@ -722,6 +747,8 @@ UnixEndpoint::_Spawn(UnixEndpoint* connectingEndpoint, UnixFifo* fifo)
PeerAddress().SetTo(&connectingEndpoint->socket->address);
fCredentials = listeningEndpoint->fCredentials;
fState = UNIX_ENDPOINT_CONNECTED;
}

View File

@ -76,6 +76,7 @@ public:
ssize_t Receivable();
status_t SetReceiveBufferSize(size_t size);
status_t GetPeerCredentials(ucred* credentials);
status_t Shutdown(int direction);
@ -95,7 +96,8 @@ public:
}
private:
void _Spawn(UnixEndpoint* connectingEndpoint, UnixFifo* fifo);
void _Spawn(UnixEndpoint* connectingEndpoint,
UnixEndpoint* listeningEndpoint, UnixFifo* fifo);
void _Disconnect();
status_t _LockConnectedEndpoints(UnixEndpointLocker& locker,
UnixEndpointLocker& peerLocker);
@ -115,8 +117,8 @@ private:
UnixFifo* fReceiveFifo;
unix_endpoint_state fState;
sem_id fAcceptSemaphore;
ucred fCredentials;
bool fIsChild;
};
#endif // UNIX_ENDPOINT_H

View File

@ -132,6 +132,17 @@ status_t
unix_getsockopt(net_protocol *protocol, int level, int option, void *value,
int *_length)
{
UnixEndpoint* endpoint = (UnixEndpoint*)protocol;
if (level == SOL_SOCKET && option == SO_PEERCRED) {
if (*_length < (int)sizeof(ucred))
return B_BAD_VALUE;
*_length = sizeof(ucred);
return endpoint->GetPeerCredentials((ucred*)value);
}
return gSocketModule->get_option(protocol->socket, level, option, value,
_length);
}