2011-11-12 9 views
6

Unixドメインソケットをリッスンしているプログラムがあります。Unixドメインソケットに接続するプログラムを特定します。

クライアントがソケットに接続すると、どのプログラムが接続されているかを調べ、接続を許可するかどうか(ユーザー/グループの設定に基づいて)を決定します。

これはLinuxでも可能ですか?その場合はどうすればよいですか?

答えて

8

はい、これはLinuxでも可能ですが、あまり移植性がありません。これは、sendmsg/recvmsgの「補助データ」を使用して実現されます。

  • 使用SCM_CREDENTIALSsetsockopt
  • で使用SO_PASSCREDstruct ucred構造

この構造は、Linuxの中で定義されています。あなたはmsghdr.controlでこれらを入力する必要があり

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 */ 
}; 

注意し、カーネルはそれらが正しいかどうかをチェックします。

メインポータビリティ障害は、この構造は、他の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 */ 
}; 
+0

ありがとうございました。まさに私が探していたもの。移植性は問題ではありません。とにかく、コードはAndroid上でのみネイティブコードとして実行されます。 –

1

おそらくgetpeernameまたはgetsocknameが役に立ちます。私はあなたのunix socketの許可が有用であると確信しています。以下 cnicutar によって示唆されているように、あなたのaccept -edソケットが資格情報とsendmsgのための補助的なデータを使用して12

EDIT

は、はるかに優れている場合、あなたは/proc/self/fd/12内のリンクを読むかもしれません。

6

私はこのためにかなりの検索、私はあなたにSO_PEERCREDを使用する方法について、この例が表示されますソケットのピアのPID/UID/GIDを取得するためのソケットsock上:

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); 
関連する問題