Skip to content

Commit

Permalink
Enhance subid check by using library function
Browse files Browse the repository at this point in the history
Fix tab

Declare structs

Error correctly if no ranges found

Add subid-devel dependency for zuul

Signed-off-by: Martin Jackson <[email protected]>
  • Loading branch information
Martin Jackson committed Nov 30, 2022
1 parent d0fe8c4 commit 9a77dac
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 24 deletions.
1 change: 1 addition & 0 deletions playbooks/dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
- ninja-build
- openssl
- podman
- shadow-utils-subid-devel
- skopeo
- systemd
- udisks2
Expand Down
111 changes: 87 additions & 24 deletions src/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,26 @@

package cmd

/*
#cgo LDFLAGS: -l subid
#include <shadow/subid.h>
#include <stdlib.h>
#include <stdio.h>
const char *Prog = "storage";
FILE *shadow_logfd = NULL;
struct subid_range get_range(struct subid_range *ranges, int i)
{
shadow_logfd = stderr;
return ranges[i];
}
#if !defined(SUBID_ABI_MAJOR) || (SUBID_ABI_MAJOR < 4)
# define subid_get_uid_ranges get_subuid_ranges
# define subid_get_gid_ranges get_subgid_ranges
#endif
*/
import "C"

import (
"bufio"
"errors"
"fmt"
"io/ioutil"
Expand All @@ -26,6 +44,7 @@ import (
"path/filepath"
"strings"
"syscall"
"unsafe"

"github.com/containers/toolbox/pkg/podman"
"github.com/containers/toolbox/pkg/utils"
Expand Down Expand Up @@ -66,6 +85,13 @@ type exitError struct {
err error
}

type subIDRange struct {
Start int
Length int
}

type ranges []subIDRange

func (e *exitError) Error() string {
if e.err != nil {
return e.err.Error()
Expand Down Expand Up @@ -141,15 +167,15 @@ func preRun(cmd *cobra.Command, args []string) error {
logrus.Debugf("Running on a cgroups v%d host", cgroupsVersion)

if currentUser.Uid != "0" {
logrus.Debugf("Checking if /etc/subgid and /etc/subuid have entries for user %s",
logrus.Debugf("Checking for subuid and subgid have entries for user %s",
currentUser.Username)

if _, err := validateSubIDFile("/etc/subuid"); err != nil {
return newSubIDFileError()
if _, err := validateSubIDRange(currentUser.Username, true); err != nil {
return newSubIDError()
}

if _, err := validateSubIDFile("/etc/subgid"); err != nil {
return newSubIDFileError()
if _, err := validateSubIDRange(currentUser.Username, false); err != nil {
return newSubIDError()
}
}
}
Expand Down Expand Up @@ -319,9 +345,9 @@ func migrate() error {
return nil
}

func newSubIDFileError() error {
func newSubIDError() error {
var builder strings.Builder
fmt.Fprintf(&builder, "/etc/subgid and /etc/subuid don't have entries for user %s\n", currentUser.Username)
fmt.Fprintf(&builder, "Missing subuid and/or subgid entries for user %s\n", currentUser.Username)
fmt.Fprintf(&builder, "See the podman(1), subgid(5), subuid(5) and usermod(8) manuals for more\n")
fmt.Fprintf(&builder, "information.")

Expand Down Expand Up @@ -392,28 +418,65 @@ func setUpLoggers() error {
return nil
}

func validateSubIDFile(path string) (bool, error) {
logrus.Debugf("Validating sub-ID file %s", path)
func validateSubIDRange(username string, isUser bool) (ranges, error) {
var ret ranges

file, err := os.Open(path)
if err != nil {
logrus.Debugf("Validating sub-ID file: failed to open %s: %s", path, err)
return false, fmt.Errorf("failed to open %s", path)
queryType := ""

if isUser {
queryType = "subuid"
} else {
queryType = "subgid"
}

scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
uidstr := ""

prefixes := []string{currentUser.Username + ":", currentUser.Uid + ":"}
if username == "ALL" {
return nil, errors.New("username ALL not supported")
}

for scanner.Scan() {
line := scanner.Text()
for _, prefix := range prefixes {
if strings.HasPrefix(line, prefix) {
return true, nil
}
if u, err := user.Lookup(username); err == nil {
uidstr = u.Uid
}

cUsername := C.CString(username)
defer C.free(unsafe.Pointer(cUsername))

cuidstr := C.CString(uidstr)
defer C.free(unsafe.Pointer(cuidstr))

var nRanges C.int
var cRanges *C.struct_subid_range
if isUser {
nRanges = C.subid_get_uid_ranges(cUsername, &cRanges)
if nRanges <= 0 {
nRanges = C.subid_get_uid_ranges(cuidstr, &cRanges)
}
} else {
nRanges = C.subid_get_gid_ranges(cUsername, &cRanges)
if nRanges <= 0 {
nRanges = C.subid_get_gid_ranges(cuidstr, &cRanges)
}
}
if nRanges <= 0 {
return nil, errors.New("cannot read subids")
}
defer C.free(unsafe.Pointer(cRanges))

return false, fmt.Errorf("failed to find an entry for user %s in %s", currentUser.Username, path)
for i := 0; i < int(nRanges); i++ {
r := C.get_range(cRanges, C.int(i))
newRange := subIDRange{
Start: int(r.start),
Length: int(r.count),
}
ret = append(ret, newRange)

logrus.Debugf("Found %s range %d for %s: start [%d] length [%d]",
queryType,
i,
username,
r.start,
r.count)
}
return ret, nil
}

0 comments on commit 9a77dac

Please sign in to comment.