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

おそらくgetpeernameまたはgetsocknameが役立つ可能性があります。そして私はあなたのUNIXソケットの許可が役に立つと思います(それは確かではありません)。また、 -edソケットが12/proc/self/fd/12の場合は、内部のリンクを読むことができます。accept

編集

以下のcnicutarで提案されているように、資格情報に補助データを使用するsendmsg方がはるかに優れています。

于 2011-11-12T14:07:59.713 に答える