I'm trying to get the Unix socket peer credentials in python.

I am using this piece of code for that:

peercred = conn.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize("3i"))
pid, uid, gid = struct.unpack("3i", peercred)

This works correctly in Linux, but in OpenBSD the order is different. In OpenBsd the order is [uid, gid, pid] instead.

What is causing this difference? How do I know when to use which order?

The linux systems I tried were running on a x86_64 architecture and the openbsd system was on a amd64 architecture.


I'm no python programmer, but I guess you should special case your code based on sys.platform.

SO_PEERCRED is not a standardized interface, and the actual structure / binary interface is different between the systems.

On Linux, as defined in /usr/include/bits/socket.h:

struct ucred {
        __u32   pid;
        __u32   uid;
        __u32   gid;

On OpenBSD, as defined in /usr/include/sys/socket.h:

struct sockpeercred {
        uid_t           uid;            /* effective user id */
        gid_t           gid;            /* effective group id */
        pid_t           pid;

(uid_t, gid_t and pid_t are also 32bit on OpenBSD)

Other systems (eg. solaris, FreeBSD) have a completely different interface -- for some code that gets the peer credentials in a "system-independent" manner you could look at the update_client_creds() function from the heimdal source code (which is using the getpeereid(3) library function on OpenBSD and FreeBSD instead of directly SO_PEERCRED or LOCAL_PEERCRED).

In any case, the credentials got this way will be those of the process that called connect(2) or listen(2) on the socket (a process that may no longer exist), not necessarily those of the process actually using the socket by writing to or reading from it.


You could use cffi and the "API level" approach. This requires a C compiler, although it is possible to do the compiling on a compatible system and then re-use the result.


Note that this works independently of the exact C layout of struct passwd (it is “API level”, as opposed to “ABI level”).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.