How to create Unix Domain Socket with a specific permissions in C?

后端 未结 3 1888
一个人的身影
一个人的身影 2020-12-29 21:39

I have a simple code, like:

sockaddr_un address;
address.sun_family = AF_UNIX;
strcpy(address.sun_path, path);
unlink(path);

int fd = socket(AF_UNIX, SOCK_S         


        
相关标签:
3条回答
  • 2020-12-29 22:31

    Forking, using umask and passing back the fd is the only portable way I can think of. Having a directory for the socket is better in any case, for example nobody can delete the socket if the directory doesn't ahve the proper permissions, and creating diretcories can be done atomically.

    The bigger problem is that relying on permissions is not portable - many BSD-derived socket stacks simply ignore the permissions of enclosing directories and/or the socket itself.

    On GNU/Linux systems, you cna do it by calling fchmod on the socket fd after socket() and before bind()

    0 讨论(0)
  • 2020-12-29 22:33

    I had the best luck using chmod() (NOT fchmod) using the file name for the unix domain socket after calling socket(), bind(), but, before calling listen().

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

    . . . . .

    0 讨论(0)
  • 2020-12-29 22:36

    Another solution is to create a directory with the desired permissions, and then create the socket inside it (example code without any regard for error checking and buffer overflows):

    // 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);
    
    0 讨论(0)
提交回复
热议问题