14

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

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

这在 Linux 下是否可行,如果可以,如何实现?

4

3 回答 3

16

是的,这在 Linux 上是可能的,但它不是很便携。sendmsg它是使用带有/的所谓“辅助数据”来实现的recvmsg

  • SO_PASSCRED与_setsockopt
  • 用途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 */
};
于 2011-11-12T14:10:14.770 回答
10

我对此进行了相当多的搜索,因此我将向您展示如何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);
于 2016-03-06T13:08:34.447 回答
2

也许getpeernamegetsockname可以提供帮助。而且我认为您的unix 套接字的许可很有用(不确定)。/proc/self/fd/12如果您的accept-ed 套接字是 12 ,您可能会阅读里面的链接。

编辑

使用辅助数据作为凭据,并且sendmsg效果要好得多,如下面的cnicutar建议的那样。

于 2011-11-12T14:07:59.713 回答