Created
July 23, 2022 12:44
-
-
Save denisoster/88a013adca06a9ca6e2af44a0e8dc591 to your computer and use it in GitHub Desktop.
Podman with support Name Service Switch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go | |
--- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go (revision 932822ab4b4d937de75228638b2916885fff444a) | |
+++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go (date 1658575026063) | |
@@ -6,9 +6,15 @@ | |
import ( | |
"io" | |
"os" | |
+ "fmt" | |
+ "sync" | |
+ "bytes" | |
+ "os/exec" | |
+ "path/filepath" | |
"strconv" | |
"golang.org/x/sys/unix" | |
+ "github.com/containers/storage/pkg/system" | |
) | |
// Unix-specific path to the passwd and group formatted files. | |
@@ -17,12 +23,17 @@ | |
unixGroupPath = "/etc/group" | |
) | |
+var ( | |
+ entOnce sync.Once | |
+ getentCmd string | |
+) | |
+ | |
// LookupUser looks up a user by their username in /etc/passwd. If the user | |
// cannot be found (or there is no /etc/passwd file on the filesystem), then | |
// LookupUser returns an error. | |
-func LookupUser(username string) (User, error) { | |
- return lookupUserFunc(func(u User) bool { | |
- return u.Name == username | |
+func LookupUser(name string) (User, error) { | |
+ return getentUser(name, func(u User) bool { | |
+ return u.Name == name | |
}) | |
} | |
@@ -30,40 +41,17 @@ | |
// be found (or there is no /etc/passwd file on the filesystem), then LookupId | |
// returns an error. | |
func LookupUid(uid int) (User, error) { | |
- return lookupUserFunc(func(u User) bool { | |
+ return getentUser(string(uid), func(u User) bool { | |
return u.Uid == uid | |
}) | |
} | |
-func lookupUserFunc(filter func(u User) bool) (User, error) { | |
- // Get operating system-specific passwd reader-closer. | |
- passwd, err := GetPasswd() | |
- if err != nil { | |
- return User{}, err | |
- } | |
- defer passwd.Close() | |
- | |
- // Get the users. | |
- users, err := ParsePasswdFilter(passwd, filter) | |
- if err != nil { | |
- return User{}, err | |
- } | |
- | |
- // No user entries found. | |
- if len(users) == 0 { | |
- return User{}, ErrNoPasswdEntries | |
- } | |
- | |
- // Assume the first entry is the "correct" one. | |
- return users[0], nil | |
-} | |
- | |
// LookupGroup looks up a group by its name in /etc/group. If the group cannot | |
// be found (or there is no /etc/group file on the filesystem), then LookupGroup | |
// returns an error. | |
-func LookupGroup(groupname string) (Group, error) { | |
- return lookupGroupFunc(func(g Group) bool { | |
- return g.Name == groupname | |
+func LookupGroup(name string) (Group, error) { | |
+ return getentGroup(fmt.Sprintf("%s %s", "group", name), func(g Group) bool { | |
+ return g.Name == name | |
}) | |
} | |
@@ -71,34 +59,100 @@ | |
// be found (or there is no /etc/group file on the filesystem), then LookupGid | |
// returns an error. | |
func LookupGid(gid int) (Group, error) { | |
- return lookupGroupFunc(func(g Group) bool { | |
+ return getentGroup(fmt.Sprintf("%s %d", "group", gid), func(g Group) bool { | |
return g.Gid == gid | |
}) | |
} | |
-func lookupGroupFunc(filter func(g Group) bool) (Group, error) { | |
- // Get operating system-specific group reader-closer. | |
- group, err := GetGroup() | |
+func getentUser(value string, filter func(u User) bool) (User, error) { | |
+ passwd, err := callGetent("passwd", value) | |
+ | |
+ if err != nil { | |
+ return User{}, err | |
+ } | |
+ | |
+ users, err := ParsePasswdFilter(passwd, filter) | |
+ | |
+ if err != nil { | |
+ return User{}, err | |
+ } | |
+ | |
+ if len(users) == 0 { | |
+ return User{}, fmt.Errorf("getent failed to find passwd entry for %q", value) | |
+ } | |
+ | |
+ return users[0], nil | |
+} | |
+ | |
+func getentGroup(value string, filter func(g Group) bool) (Group, error) { | |
+ group, err := callGetent("group", value) | |
+ | |
if err != nil { | |
return Group{}, err | |
} | |
- defer group.Close() | |
- // Get the users. | |
groups, err := ParseGroupFilter(group, filter) | |
+ | |
if err != nil { | |
return Group{}, err | |
} | |
- // No user entries found. | |
if len(groups) == 0 { | |
- return Group{}, ErrNoGroupEntries | |
+ return Group{}, fmt.Errorf("getent failed to find groups entry for %q", value) | |
} | |
- // Assume the first entry is the "correct" one. | |
return groups[0], nil | |
} | |
+func callGetent(database string, key string) (io.Reader, error) { | |
+ entOnce.Do(func() { getentCmd, _ = resolveBinary("getent") }) | |
+ // if no `getent` command on host, can't do anything else | |
+ if getentCmd == "" { | |
+ return nil, fmt.Errorf("unable to find getent command") | |
+ } | |
+ out, err := execCmd(getentCmd, database, key) | |
+ if err != nil { | |
+ exitCode, errC := system.GetExitCode(err) | |
+ if errC != nil { | |
+ return nil, err | |
+ } | |
+ switch exitCode { | |
+ case 1: | |
+ return nil, fmt.Errorf("getent reported invalid parameters/database unknown") | |
+ case 2: | |
+ return nil, fmt.Errorf("getent unable to find entry %q in %s database", key, database) | |
+ case 3: | |
+ return nil, fmt.Errorf("getent database doesn't support enumeration") | |
+ default: | |
+ return nil, err | |
+ } | |
+ | |
+ } | |
+ return bytes.NewReader(out), nil | |
+} | |
+ | |
+func resolveBinary(binname string) (string, error) { | |
+ binaryPath, err := exec.LookPath(binname) | |
+ if err != nil { | |
+ return "", err | |
+ } | |
+ resolvedPath, err := filepath.EvalSymlinks(binaryPath) | |
+ if err != nil { | |
+ return "", err | |
+ } | |
+ // only return no error if the final resolved binary basename | |
+ // matches what was searched for | |
+ if filepath.Base(resolvedPath) == binname { | |
+ return resolvedPath, nil | |
+ } | |
+ return "", fmt.Errorf("Binary %q does not resolve to a binary of that name in $PATH (%q)", binname, resolvedPath) | |
+} | |
+ | |
+func execCmd(cmd string, arg ...string) ([]byte, error) { | |
+ execCmd := exec.Command(cmd, arg...) | |
+ return execCmd.CombinedOutput() | |
+} | |
+ | |
func GetPasswdPath() (string, error) { | |
return unixPasswdPath, nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Maintainer: Morten Linderud <foxboron@archlinux.org> | |
# Maintainer: David Runge <dvzrv@archlinux.org> | |
# Contributor: Bartłomiej Piotrowski <bpiotrowski@archlinux.org> | |
pkgbase=podman | |
pkgname=(podman podman-docker) | |
pkgver=4.1.1 | |
pkgrel=3 | |
pkgdesc='Tool and library for running OCI-based containers in pods' | |
arch=(x86_64) | |
url='https://github.com/containers/podman' | |
license=(Apache) | |
makedepends=(apparmor btrfs-progs catatonit device-mapper go go-md2man git gpgme libseccomp systemd) | |
# https://github.com/containers/podman/issues/13297 | |
options=(!lto) | |
source=(git+$url#tag=v$pkgver?signed | |
nsswitch.patch | |
) | |
sha256sums=('SKIP' | |
'SKIP') | |
prepare() { | |
cd $pkgname | |
patch --strip=1 --input="${srcdir}/nsswitch.patch" | |
} | |
pkgver() { | |
cd $pkgname | |
git describe --tags | sed 's/^v//;s/-/+/g' | |
} | |
build() { | |
# NOTE: the BUILDTAGS may change over time | |
export BUILDTAGS='apparmor seccomp systemd' | |
export CGO_CPPFLAGS="${CPPFLAGS}" | |
export CGO_CFLAGS="${CFLAGS}" | |
export CGO_CXXFLAGS="${CXXFLAGS}" | |
export CGO_LDFLAGS="${LDFLAGS}" | |
export GOFLAGS="-buildmode=pie -trimpath" | |
make EXTRA_LDFLAGS='-s -w -linkmode=external' -C $pkgbase | |
make docker-docs -C $pkgbase | |
} | |
package_podman() { | |
depends=(catatonit conmon containers-common crun iptables libdevmapper.so | |
libgpgme.so libseccomp.so slirp4netns) | |
optdepends=( | |
'apparmor: for AppArmor support' | |
'btrfs-progs: support btrfs backend devices' | |
'netavark: for a new container-network-stack implementation' | |
'podman-compose: for docker-compose compatibility' | |
'podman-docker: for Docker-compatible CLI' | |
) | |
make install install.completions DESTDIR="$pkgdir" PREFIX=/usr LIBEXECDIR=/usr/lib -C $pkgbase | |
# remove man pages provided by containers-common | |
rm -rvf "$pkgdir/usr/share/man/man5" | |
} | |
package_podman-docker() { | |
pkgdesc='Emulate Docker CLI using podman' | |
depends=(podman) | |
conflicts=(docker) | |
provides=(docker) | |
make -j1 install.docker-full DESTDIR="$pkgdir" PREFIX=/usr -C $pkgbase | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment