我有一个正在监听 Unix 域套接字的程序。
当客户端连接到套接字时,我想找出连接的程序,然后决定是否允许连接(基于用户/组设置)。
这在 Linux 下是否可行,如果可以,如何实现?
我有一个正在监听 Unix 域套接字的程序。
当客户端连接到套接字时,我想找出连接的程序,然后决定是否允许连接(基于用户/组设置)。
这在 Linux 下是否可行,如果可以,如何实现?
是的,这在 Linux 上是可能的,但它不是很便携。sendmsg
它是使用带有/的所谓“辅助数据”来实现的recvmsg
。
SO_PASSCRED
与_setsockopt
SCM_CREDENTIALS
及struct 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 */
};
我对此进行了相当多的搜索,因此我将向您展示如何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);
也许getpeername或getsockname可以提供帮助。而且我认为您的unix 套接字的许可很有用(不确定)。/proc/self/fd/12
如果您的accept
-ed 套接字是 12 ,您可能会阅读里面的链接。
编辑
使用辅助数据作为凭据,并且sendmsg
效果要好得多,如下面的cnicutar建议的那样。