unix_socket.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // +build linux freebsd
  2. package sockets
  3. import (
  4. "fmt"
  5. "net"
  6. "os"
  7. "strconv"
  8. "syscall"
  9. "github.com/Sirupsen/logrus"
  10. "github.com/docker/docker/pkg/listenbuffer"
  11. "github.com/opencontainers/runc/libcontainer/user"
  12. )
  13. // NewUnixSocket creates a unix socket with the specified path and group.
  14. // The channel passed is used to activate the listenbuffer when the caller is ready
  15. // to accept connections.
  16. func NewUnixSocket(path, group string, activate <-chan struct{}) (net.Listener, error) {
  17. if err := syscall.Unlink(path); err != nil && !os.IsNotExist(err) {
  18. return nil, err
  19. }
  20. mask := syscall.Umask(0777)
  21. defer syscall.Umask(mask)
  22. l, err := listenbuffer.NewListenBuffer("unix", path, activate)
  23. if err != nil {
  24. return nil, err
  25. }
  26. if err := setSocketGroup(path, group); err != nil {
  27. l.Close()
  28. return nil, err
  29. }
  30. if err := os.Chmod(path, 0660); err != nil {
  31. l.Close()
  32. return nil, err
  33. }
  34. return l, nil
  35. }
  36. func setSocketGroup(path, group string) error {
  37. if group == "" {
  38. return nil
  39. }
  40. if err := changeGroup(path, group); err != nil {
  41. if group != "docker" {
  42. return err
  43. }
  44. logrus.Debugf("Warning: could not change group %s to docker: %v", path, err)
  45. }
  46. return nil
  47. }
  48. func changeGroup(path string, nameOrGid string) error {
  49. gid, err := lookupGidByName(nameOrGid)
  50. if err != nil {
  51. return err
  52. }
  53. logrus.Debugf("%s group found. gid: %d", nameOrGid, gid)
  54. return os.Chown(path, 0, gid)
  55. }
  56. func lookupGidByName(nameOrGid string) (int, error) {
  57. groupFile, err := user.GetGroupPath()
  58. if err != nil {
  59. return -1, err
  60. }
  61. groups, err := user.ParseGroupFileFilter(groupFile, func(g user.Group) bool {
  62. return g.Name == nameOrGid || strconv.Itoa(g.Gid) == nameOrGid
  63. })
  64. if err != nil {
  65. return -1, err
  66. }
  67. if groups != nil && len(groups) > 0 {
  68. return groups[0].Gid, nil
  69. }
  70. gid, err := strconv.Atoi(nameOrGid)
  71. if err == nil {
  72. logrus.Warnf("Could not find GID %d", gid)
  73. return gid, nil
  74. }
  75. return -1, fmt.Errorf("Group %s not found", nameOrGid)
  76. }