useros

package module
v0.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 14, 2023 License: MIT Imports: 12 Imported by: 0

README

Wrapper for pkg.go.dev/os that checks file permissions for a given user, when the process is executing as root, avoiding a setuid call.

Only linux is supported, on other OSes it is a simple wrapper around the pkg.go.dev/os package without further restrictions. If not run as the root user, it also simply wrapps pkg.go.dev/os. We enforce the standard permission model (user, group, other) as well as ACL lists. Since we still act as root, it works well with standard linux mounts, but will fail for e.g. kerberized nfs mounts if the root user is not mapped to the remote root.

Since we need to check file permissions before doing the actual file operation, we cannot garantee that the resulting operation is atomic.

Use at own risk. Usage is fairly simple:

useros := User{UID: 1000, GID: 1000, Groups: []int{1001}}.OS()

f, err := useros.Open("/path/to/file/name")

It implements the following interface:

type OS interface {
	Chmod(name string, mode os.FileMode) error
	Chown(name string, uid, gid int) error
	Chtimes(name string, atime, mtime time.Time) error
	Lchown(name string, uid, gid int) error
	Mkdir(name string, perm os.FileMode) error
	MkdirAll(path string, perm os.FileMode) error
	ReadFile(name string) ([]byte, error)
	Readlink(name string) (string, error)
	Remove(name string) error
	RemoveAll(path string) error
	Rename(oldpath, newpath string) error
	Symlink(oldname, newname string) error
	Truncate(name string, size int64) error
	WriteFile(name string, data []byte, perm os.FileMode) error
	Stat(name string) (os.FileInfo, error)
	Lstat(name string) (os.FileInfo, error)
	Create(name string) (*os.File, error)
	Open(name string) (*os.File, error)
	OpenFile(name string, flag int, perm os.FileMode) (*os.File, error)
	ReadDir(name string) ([]os.DirEntry, error)
}

Note: to run the golang tests, execute as root.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrTypeAssertion = errors.New("type assertion")
View Source
var LogHandler func(error)

LogHandler is a configurable log handler

Functions

func ResolveSymlinks(path string) ([]string, error)

ResolveSymlinks returns the list of paths that is followed to get the the specified path.

func TraversedDirectories added in v0.1.2

func TraversedDirectories(path string) ([]string, error)

TraversedDirectories returns the list of directories that is followed to get the the specified inode. We first clean up the path, i.e. .. is replaced. We also follow symlinks. E.g. /sbin/../bin/bash would return [/, /usr, /usr/bin] because /bin is symlink to /usr/bin. The last directory should be the real path of the directory of the inode. Note that the existence or type of the inode itself is not checked.

Types

type File

type File interface {
	Chdir() error
	Chmod(os.FileMode) error
	Chown(uid, gid int) error
	Close() error
	Fd() uintptr
	Name() string
	Read(b []byte) (int, error)
	ReadAt(b []byte, off int64) (int, error)
	ReadDir(n int) ([]os.DirEntry, error)
	ReadFrom(r io.Reader) (int64, error)
	Readdir(n int) ([]os.FileInfo, error)
	Readdirnames(n int) ([]string, error)
	Seek(offset int64, whence int) (int64, error)
	SetDeadline(t time.Time) error
	SetReadDeadline(t time.Time) error
	SetWriteDeadline(t time.Time) error
	Stat() (os.FileInfo, error)
	Sync() error
	SyscallConn() (syscall.RawConn, error)
	Truncate(size int64) error
	Write(b []byte) (int, error)
	WriteAt(b []byte, off int64) (int, error)
	WriteString(s string) (int, error)
}

type OS

type OS interface {
	CurrentUser() User
	Chmod(name string, mode os.FileMode) error
	Chown(name string, uid, gid int) error
	Chtimes(name string, atime, mtime time.Time) error
	Lchown(name string, uid, gid int) error
	Mkdir(name string, perm os.FileMode) error
	MkdirAll(path string, perm os.FileMode) error
	ReadFile(name string) ([]byte, error)
	Readlink(name string) (string, error)
	Remove(name string) error
	RemoveAll(path string) error
	Rename(oldpath, newpath string) error
	Symlink(oldname, newname string) error
	Truncate(name string, size int64) error
	WriteFile(name string, data []byte, perm os.FileMode) error
	Stat(name string) (os.FileInfo, error)
	Lstat(name string) (os.FileInfo, error)
	Create(name string) (File, error)
	Open(name string) (File, error)
	OpenFile(name string, flag int, perm os.FileMode) (File, error)
	ReadDir(name string) ([]os.DirEntry, error)
	EvalSymlinks(name string) (string, error)
	Walk(name string, walkFn filepath.WalkFunc) error
}

func Default

func Default() OS

Default OS implementation is a simple wrapper around the pkg.go.dev/os functions. Mainly usefull in situations where conditionally the default OS or a user view to the OS is needed.

type Permission

type Permission uint32
const (
	Read    Permission = 4
	Write   Permission = 2
	Execute Permission = 1
)

func (Permission) Check

func (p Permission) Check(m os.FileMode) bool

type User

type User struct {
	UID    int
	GID    int
	Groups []int
}

func (User) CanReadInode

func (u User) CanReadInode(path string) error

CanReadInode checks whether the user can read the file inode at the specified path, i.e. whether the inode can be statted (= execution bit on the parent directory). The inode itself doesn't have to exist, its parent directory should exist. If nil is returned, the inode is readable by the user.

func (User) CanReadObject

func (u User) CanReadObject(path string) error

CanReadObject checks whether the user can read the file or directory at the specified path. The file or directory needs to exist, as its permission bits are checked. Symlinks are followed. If nil is returned, the object is readable by the user.

func (User) CanWriteInode

func (u User) CanWriteInode(path string) error

CanWriteInode checks whether the user can write to the file inode at the specified path. The inode itself doesn't have to exist, its parent directory should exist. If nil is returned, the inode is writable by the user.

func (User) CanWriteObject

func (u User) CanWriteObject(path string) error

CanWriteObject checks whether the user can write to the file or directory at the specified path. The file or directory needs to exist, as its permission bits are checked. Symlinks are followed. If nil is returned, the object is writable by the user.

func (User) Lowns

func (u User) Lowns(path string) error

Lowns checks whether the user owns the file or directory at the specified path. The file or directory needs to exist, as its owner is checked. Symlinks are not followed. If nil is returned, the object is owned by the user.

func (User) OS

func (u User) OS() OS

OS returns a simulated version of os as if the user would run the commands.

func (User) Owns

func (u User) Owns(path string) error

Owns checks whether the user owns the file or directory at the specified path. The file or directory needs to exist, as its owner is checked. Symlinks are followed. If nil is returned, the object is owned by the user.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL