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

时间:2011-11-12 14:02:03

标签: linux unix-socket

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

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

这在Linux下是否可行,若然,怎么办?

3 个答案:

答案 0 :(得分:12)

是的,这在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 */
};

请注意,您必须在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 */
};

答案 1 :(得分:8)

我搜索了这一点,所以我将向您展示如何在套接字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);

答案 2 :(得分:2)

或许getpeernamegetsockname可以提供帮助。我认为你unix socket的许可是有用的(不确定)。如果/proc/self/fd/12 - ed套接字为12,您可以阅读accept内的链接。

修改

使用凭据的辅助数据和sendmsg要好得多,如下面的 cnicutar 所示。