github.com/damirazo/docker@v1.9.0/pkg/sockets/unix_socket.go (about)

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