如何在C中创建具有特定权限的Unix Domain Socket?

时间:2013-11-24 06:16:32

标签: c sockets unix unix-socket umask

我有一个简单的代码,例如:

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()调用同步的情况下实现我的目标。

3 个答案:

答案 0 :(得分:21)

另一个解决方案是创建一个具有所需权限的目录,然后在其中创建套接字(示例代码,不考虑错误检查和缓冲区溢出):

// 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);

答案 1 :(得分:12)

在调用socket(),bind()之后,在调用listen()之前使用chmod()(非fchmod)使用unix域套接字的文件名,运气最好。

  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);
  }

。 。 。 。 。

答案 2 :(得分:5)

分叉,使用umask并传回fd是我能想到的唯一可移植方式。拥有套接字的目录在任何情况下都是更好的,例如,如果目录没有正确的权限,则没有人可以删除套接字,并且可以原子方式创建目录。

更大的问题是依赖权限是不可移植的 - 许多BSD派生的套接字堆栈只是忽略了封闭目录和/或套接字本身的权限。

在GNU / Linux系统上,你可以通过在socket()之后和bind()

之前调用socket fd上的fchmod来实现它