Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 47 additions & 6 deletions apis/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/alibaba/pouch/daemon/config"
"github.com/alibaba/pouch/daemon/mgr"
"github.com/alibaba/pouch/pkg/httputils"
"github.com/alibaba/pouch/pkg/user"

"github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -112,13 +113,53 @@ func getListener(addr string, tlsConfig *tls.Config) (net.Listener, error) {
}
return l, err
case "unix":
if err := syscall.Unlink(addrParts[1]); err != nil && !os.IsNotExist(err) {
return nil, err
}
mask := syscall.Umask(0777)
defer syscall.Umask(mask)
return net.Listen("unix", addrParts[1])
return newUnixSocket(addrParts[1])

default:
return nil, fmt.Errorf("only unix socket or tcp address is support")
}
}

func newUnixSocket(path string) (net.Listener, error) {
if err := syscall.Unlink(path); err != nil && !os.IsNotExist(err) {
return nil, err
}
oldmask := syscall.Umask(0777)
defer syscall.Umask(oldmask)
l, err := net.Listen("unix", path)
if err != nil {
return nil, err
}

// chmod unix socket, make other group writable
if err := os.Chmod(path, 0660); err != nil {
l.Close()
return nil, fmt.Errorf("failed to chmod %s: %s", path, err)
}

gid, err := user.ParseID(user.GroupFile, "pouch", func(line, str string, idInt int, idErr error) (uint32, bool) {
var (
name, placeholder string
id int
)

user.ParseString(line, &name, &placeholder, &id)
if str == name {
return uint32(id), true
}
return 0, false
})
if err != nil {
// ignore error when group pouch not exist, group pouch should to be
// created before pouchd started, it means code not create pouch group
logrus.Warnf("failed to find group pouch, cannot change unix socket %s to pouch group", path)
return l, nil
}

// chown unix socket with group pouch
if err := os.Chown(path, 0, int(gid)); err != nil {
l.Close()
return nil, fmt.Errorf("failed to chown %s: %s", path, err)
}
return l, nil
}
32 changes: 17 additions & 15 deletions pkg/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
)

var (
passwdFile = "/etc/passwd"
groupFile = "/etc/group"
// PasswdFile keeps user passwd information
PasswdFile = "/etc/passwd"
// GroupFile keeps group information
GroupFile = "/etc/group"

minID = 0
maxID = 1<<31 - 1 // compatible for 32-bit OS
Expand Down Expand Up @@ -60,12 +62,12 @@ func Get(path string, user string) (uint32, uint32, error) {
err error
)

parseString(user, &uidStr, &gidStr)
ParseString(user, &uidStr, &gidStr)

// get uid from /etc/passwd
uid, err = parseID(filepath.Join(path, passwdFile), uidStr, func(line, str string, idInt int, idErr error) (uint32, bool) {
uid, err = ParseID(filepath.Join(path, PasswdFile), uidStr, func(line, str string, idInt int, idErr error) (uint32, bool) {
var up uidParser
parseString(line, &up.user, &up.placeholder, &up.uid)
ParseString(line, &up.user, &up.placeholder, &up.uid)
if (idErr == nil && idInt == up.uid) || str == up.user {
return uint32(up.uid), true
}
Expand All @@ -77,9 +79,9 @@ func Get(path string, user string) (uint32, uint32, error) {

// if gidStr is null, then get gid from /etc/passwd
if len(gidStr) == 0 {
gid, err = parseID(filepath.Join(path, passwdFile), uidStr, func(line, str string, idInt int, idErr error) (uint32, bool) {
gid, err = ParseID(filepath.Join(path, PasswdFile), uidStr, func(line, str string, idInt int, idErr error) (uint32, bool) {
var up uidParser
parseString(line, &up.user, &up.placeholder, &up.uid, &up.gid)
ParseString(line, &up.user, &up.placeholder, &up.uid, &up.gid)
if (idErr == nil && idInt == up.uid) || str == up.user {
return uint32(up.gid), true
}
Expand All @@ -89,9 +91,9 @@ func Get(path string, user string) (uint32, uint32, error) {
return 0, 0, err
}
} else {
gid, err = parseID(filepath.Join(path, groupFile), gidStr, func(line, str string, idInt int, idErr error) (uint32, bool) {
gid, err = ParseID(filepath.Join(path, GroupFile), gidStr, func(line, str string, idInt int, idErr error) (uint32, bool) {
var gp gidParser
parseString(line, &gp.group, &gp.placeholder, &gp.gid)
ParseString(line, &gp.group, &gp.placeholder, &gp.gid)
if (idErr == nil && idInt == gp.gid) || str == gp.group {
return uint32(gp.gid), true
}
Expand All @@ -115,7 +117,7 @@ func GetIntegerID(user string) (uint32, uint32) {

// if uid gid can not be parsed successfully, return default user root
var uid, gid int
parseString(user, &uid, &gid)
ParseString(user, &uid, &gid)
return uint32(uid), uint32(gid)
}

Expand All @@ -135,13 +137,13 @@ func GetAdditionalGids(groups []string) []uint32 {
return additionalGids
}

// parseID parses uid from /etc/passwd.
func parseID(file, str string, parserFilter filterFunc) (uint32, error) {
// ParseID parses id or name from given file.
func ParseID(file, str string, parserFilter filterFunc) (uint32, error) {
idInt, idErr := strconv.Atoi(str)

ba, err := ioutil.ReadFile(file)
if err != nil {
return 0, fmt.Errorf("failed to read passwd file %s: %s", passwdFile, err)
return 0, fmt.Errorf("failed to read passwd file %s: %s", PasswdFile, err)
}

scanner := bufio.NewScanner(bytes.NewReader(ba))
Expand Down Expand Up @@ -180,8 +182,8 @@ func isUnknownUser(id int) (bool, error) {
return true, nil
}

// parseString parses line in format a:b:c.
func parseString(line string, v ...interface{}) {
// ParseString parses line in format a:b:c.
func ParseString(line string, v ...interface{}) {
splits := strings.Split(line, ":")
for i, s := range splits {
if len(v) <= i {
Expand Down
2 changes: 1 addition & 1 deletion pkg/user/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestParseString(t *testing.T) {
} {
var u1, u2 string
var i1, i2 int
parseString(l, &u1, &u2, &i1, &i2)
ParseString(l, &u1, &u2, &i1, &i2)
assert.Equal(fmt.Sprintf("%s:%s:%d:%d", u1, u2, i1, i2), l)
}
}
Expand Down