web-dev-qa-db-ja.com

Cで特定の権限を持つUnixドメインソケットを作成する方法は?

私は次のような簡単なコードを持っています:

_sockaddr_un address;
address.Sun_family = AF_UNIX;
strcpy(address.Sun_path, path);
unlink(path);

int fd = socket(AF_UNIX, SOCK_STREAM, 0);
bind(fd, (sockaddr*)(&address), sizeof(address));
listen(fd, 100);
_

原子的に特定のパーミッションでUnixドメインソケットファイルを作成します。例:_0777_。マニュアルでは、umaskなどに関するソケットファイルのアクセス許可については何も言及していません。たとえumaskがソケットファイルに影響する場合でも、マルチスレッドプログラムでは、それはアトミックな方法ではありません。

umask()呼び出しの同期を使用せずに私の目標を達成する方法があることを願っています。

29
abyss.7

別の解決策は、目的のアクセス許可を持つディレクトリを作成し、その中にソケットを作成することです(エラーチェックとバッファオーバーフローを考慮しないサンプルコード)。

// Create a directory with the proper permissions
mkdir(path, 0700);
// Append the name of the socket
strcat(path, "/socket_name");

// Create the socket normally
sockaddr_un address;
address.Sun_family = AF_UNIX;
strcpy(address.Sun_path, path);
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
bind(fd, (sockaddr*)(&address), sizeof(address));
listen(fd, 100);
21

Socket()、bind()を呼び出した後、listen()を呼び出す前に、Unixドメインソケットのファイル名を使用して、chmod()(fchmodではない)を使用して最高の運がありました。

  int return_value;
  const char *sock_path;
  struct sockaddr_un local;

  sock_path = "/tmp/mysocket";

  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  if (sockfd == -1)
  {
    perror("socket");
    exit(-1);
  }

  local.Sun_family = AF_UNIX; 
  strcpy(local.Sun_path, sock_path);
  unlink(local.Sun_path);
  len = strlen(local.Sun_path) + sizeof(local.Sun_family);
  bind(sockfd, (struct sockaddr *)&local, len);

  chmod(sock_path, 0777);

  retval = listen(sockfd, BACKLOG);
  if (retval == -1)
  {
    perror("listen");
    exit(-1);
  }

。 。 。 。 。

12
Don Carr

フォーク、umaskの使用、fdの返送が唯一のポータブルな方法です。ソケット用のディレクトリを用意することは、どのような場合でも優れています。たとえば、ディレクトリに適切なアクセス許可がない場合、誰もソケットを削除できず、ディレクトリなどの作成はアトミックに実行できます。

より大きな問題は、パーミッションに依存することは移植性がないことです。多くのBSD由来のソケットスタックは、ディレクトリやソケット自体を囲むパーミッションを単に無視します。

GNU/Linuxシステムでは、socket()の後、bind()の前に、ソケットfdでfchmodを呼び出すことでそれを行うことができます。

5
Anonymous