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(); _UnsetReceiveFifo();
fCredentials.pid = getpid();
fCredentials.uid = geteuid();
fCredentials.gid = getegid();
fState = UNIX_ENDPOINT_LISTENING; fState = UNIX_ENDPOINT_LISTENING;
RETURN_ERROR(B_OK); RETURN_ERROR(B_OK);
@ -352,7 +356,7 @@ UnixEndpoint::Connect(const struct sockaddr *_address)
UnixEndpointLocker connectedLocker(connectedEndpoint); UnixEndpointLocker connectedLocker(connectedEndpoint);
connectedEndpoint->_Spawn(this, peerFifo); connectedEndpoint->_Spawn(this, listeningEndpoint, peerFifo);
// update our attributes // update our attributes
_UnsetReceiveFifo(); _UnsetReceiveFifo();
@ -362,6 +366,10 @@ UnixEndpoint::Connect(const struct sockaddr *_address)
fPeerEndpoint->AddReference(); fPeerEndpoint->AddReference();
fReceiveFifo = fifo; fReceiveFifo = fifo;
fCredentials.pid = getpid();
fCredentials.uid = geteuid();
fCredentials.gid = getegid();
fifoDeleter.Detach(); fifoDeleter.Detach();
peerFifoDeleter.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 status_t
UnixEndpoint::Shutdown(int direction) UnixEndpoint::Shutdown(int direction)
{ {
@ -710,7 +734,8 @@ UnixEndpoint::Shutdown(int direction)
void void
UnixEndpoint::_Spawn(UnixEndpoint* connectingEndpoint, UnixFifo* fifo) UnixEndpoint::_Spawn(UnixEndpoint* connectingEndpoint,
UnixEndpoint* listeningEndpoint, UnixFifo* fifo)
{ {
ProtocolSocket::Open(); ProtocolSocket::Open();
@ -722,6 +747,8 @@ UnixEndpoint::_Spawn(UnixEndpoint* connectingEndpoint, UnixFifo* fifo)
PeerAddress().SetTo(&connectingEndpoint->socket->address); PeerAddress().SetTo(&connectingEndpoint->socket->address);
fCredentials = listeningEndpoint->fCredentials;
fState = UNIX_ENDPOINT_CONNECTED; fState = UNIX_ENDPOINT_CONNECTED;
} }

View File

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

View File

@ -132,6 +132,17 @@ status_t
unix_getsockopt(net_protocol *protocol, int level, int option, void *value, unix_getsockopt(net_protocol *protocol, int level, int option, void *value,
int *_length) 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, return gSocketModule->get_option(protocol->socket, level, option, value,
_length); _length);
} }