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ソケットの許可が役に立つと思います(それは確かではありません)。また、 -edソケットが12/proc/self/fd/12
の場合は、内部のリンクを読むことができます。accept
編集
以下のcnicutarで提案されているように、資格情報に補助データを使用するsendmsg
方がはるかに優れています。