3

This is kind of a programming question, but it's very Linux/Unix specific. If I get a TCP connection from localhost, is there a simple way to tell which user made the connection inside a C program without shelling out? I know this isn't too hard with a Unix domain socket.

I already know the remote IP address is localhost (::1 or 127.0.0.1) and I know the remote port number. What I don't know is the effective user id of the process that made the connection. Is there any way to discover this?

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • Possible duplicate of [How to get ip address from sock structure in c?](https://stackoverflow.com/questions/3060950/how-to-get-ip-address-from-sock-structure-in-c) I don't believe there's a way to get more than the IP address from a TCP connection. If you move to SSL/TLS, some cipher suites, like TLS-SRP and TLS-PSK, require the user to provide the credential. – jww Jun 14 '17 at 12:31
  • @jww - Windows apparently has implemented some kind of mechanism (if you the connection is from localhost) of knowing the user credentials of who made the connection. This seems all wrong to me, but I have it on reliable sources that it's true. I was wondering if there was an equivalent Linux facility since I'm being given the job of porting some code. – Omnifarious Jun 14 '17 at 15:03
  • Also see [How to find the UID of a client connected to AF_INET socket?](https://stackoverflow.com/q/44554362/608639) – jww Jun 14 '17 at 22:10
  • @jww yep, they're asking exactly the same thing. – Omnifarious Jun 14 '17 at 22:54
  • @jww - But, in my case, learning the uid of the creator of the socket is good enough. – Omnifarious Jun 15 '17 at 00:22

1 Answers1

4

On Linux, /proc/net/tcp contains information on the open TCP sockets on the system. For a connected socket, the entries look like this (the header is part of the file, other lines removed):

  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     

  11: 0100007F:C9CB 0100007F:0016 01 00000000:00000000 00:00000000 00000000  1000        0 978132 ...

The second and third columns have the endpoints of the socket, and the uid column has the effective UID of the process what created the socket. /proc/net/tcp6 is similar for IPv6. (The IP address there is 127.0.0.1, so the octets seem to be in reverse order.)

If you wanted to track the actual process(es) holding the socket, you'd need to go through all /proc/$PID/fd/$N entries, and compare the inode numbers in the socket symlinks to the inode number mentioned in the tcp socket table. But you can only see the file descriptors of your own processes, unless you're the superuser.

ilkkachu
  • 6,221
  • 16
  • 30
  • Yes, this looks like it might do it. A bit of a pain to use from inside a C program, but definitely doable. Also, very Linux specific, but I expected nothing less. I will wait a bit for someone to come up with a better answer, and if they don't I'll accept this one. Thank you. – Omnifarious Jun 14 '17 at 17:55