我有一个正在侦听Unix域套接字的程序。
当客户端连接到套接字时,我想找出连接的程序,然后决定是否允许连接(基于用户/组设置)。
这在Linux下是否可行,若然,怎么办?
答案 0 :(得分:12)
是的,这在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 */
};
答案 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)
或许getpeername或getsockname可以提供帮助。我认为你unix socket的许可是有用的(不确定)。如果/proc/self/fd/12
- ed套接字为12,您可以阅读accept
内的链接。
修改强>
使用凭据的辅助数据和sendmsg
要好得多,如下面的 cnicutar 所示。