识别连接到Unix域套接字的程序

Nil*_*nck 11 linux unix-socket

我有一个正在侦听Unix域套接字的程序.

当客户端连接到套接字时,我想找出连接的程序,然后决定是否允许连接(基于用户/组设置).

这可能在Linux下,如果是这样,怎么样?

cni*_*tar 13

是的,这在Linux上是可行的,但它不会非常便携.它是使用sendmsg/ 所谓的"辅助数据"实现的recvmsg.

  • 使用SO_PASSCREDsetsockopt
  • 使用SCM_CREDENTIALSstruct ucred结构

此结构在Linux中定义:

struct ucred {
    pid_t pid;    /* process ID of the sending process */
    uid_t uid;    /* user ID of the sending process */
    gid_t gid;    /* group ID of the sending process */
};
Run Code Online (Sandbox Code Playgroud)

请注意,您必须填写这些内容,msghdr.control内核将检查它们是否正确.

主要的可移植性障碍是这个结构在其他Unix上有所不同 - 例如在FreeBSD上它是:

struct cmsgcred {
    pid_t   cmcred_pid;          /* PID of sending process */
    uid_t   cmcred_uid;          /* real UID of sending process */
    uid_t   cmcred_euid;         /* effective UID of sending process */
    gid_t   cmcred_gid;          /* real GID of sending process */
    short   cmcred_ngroups;      /* number or groups */
    gid_t   cmcred_groups[CMGROUP_MAX];     /* groups */
};
Run Code Online (Sandbox Code Playgroud)


Zul*_*kis 9

我搜索了这一点,所以我将向您展示如何SO_PEERCRED在套接字上使用sock以获取套接字对等体的pid/uid/gid的示例:

int len;
struct ucred ucred;

len = sizeof(struct ucred);

if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) {
    //getsockopt failed
}

printf("Credentials from SO_PEERCRED: pid=%ld, euid=%ld, egid=%ld\n",
    (long) ucred.pid, (long) ucred.uid, (long) ucred.gid);
Run Code Online (Sandbox Code Playgroud)