unix_socket.go 1.7 KB

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