Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tables use tablehelpers.run #1696

Merged
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
2 changes: 1 addition & 1 deletion ee/tables/airport/table_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type airportExecutor struct {
}

func (a *airportExecutor) Exec(option string) ([]byte, error) {
return tablehelpers.Exec(a.ctx, a.slogger, 30, allowedcmd.Airport, []string{"--" + option}, false)
return tablehelpers.RunSimple(a.ctx, a.slogger, 30, allowedcmd.Airport, []string{"--" + option})
}

type executor interface {
Expand Down
2 changes: 1 addition & 1 deletion ee/tables/apple_silicon_security_policy/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TablePlugin(slogger *slog.Logger) *table.Plugin {
func (t *Table) generate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
var results []map[string]string

output, err := tablehelpers.Exec(ctx, t.slogger, 30, allowedcmd.Bputil, []string{bootPolicyUtilArgs}, false)
output, err := tablehelpers.RunSimple(ctx, t.slogger, 30, allowedcmd.Bputil, []string{bootPolicyUtilArgs})
if err != nil {
t.slogger.Log(ctx, slog.LevelInfo,
"bputil failed",
Expand Down
2 changes: 1 addition & 1 deletion ee/tables/crowdstrike/falcon_kernel_check/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TablePlugin(slogger *slog.Logger) *table.Plugin {
}

func (t *Table) generate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
output, err := tablehelpers.Exec(ctx, t.slogger, 5, allowedcmd.FalconKernelCheck, []string{}, false)
output, err := tablehelpers.RunSimple(ctx, t.slogger, 5, allowedcmd.FalconKernelCheck, []string{})
if err != nil {
t.slogger.Log(ctx, slog.LevelInfo,
"exec failed",
Expand Down
6 changes: 3 additions & 3 deletions ee/tables/crowdstrike/falconctl/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ var (
defaultOption = strings.Join(allowedOptions, " ")
)

type execFunc func(context.Context, *slog.Logger, int, allowedcmd.AllowedCommand, []string, bool, ...tablehelpers.ExecOps) ([]byte, error)
type execFunc func(context.Context, *slog.Logger, int, allowedcmd.AllowedCommand, []string, ...tablehelpers.ExecOps) ([]byte, error)

type falconctlOptionsTable struct {
slogger *slog.Logger
Expand All @@ -54,7 +54,7 @@ func NewFalconctlOptionTable(slogger *slog.Logger) *table.Plugin {
t := &falconctlOptionsTable{
slogger: slogger.With("table", "kolide_falconctl_options"),
tableName: "kolide_falconctl_options",
execFunc: tablehelpers.Exec,
execFunc: tablehelpers.RunSimple,
}

return table.NewPlugin(t.tableName, columns, t.generate)
Expand Down Expand Up @@ -92,7 +92,7 @@ OUTER:
// then the list of options to fetch. Set the command line thusly.
args := append([]string{"-g"}, options...)

output, err := t.execFunc(ctx, t.slogger, 30, allowedcmd.Falconctl, args, false)
output, err := t.execFunc(ctx, t.slogger, 30, allowedcmd.Falconctl, args)
if err != nil {
t.slogger.Log(ctx, slog.LevelInfo,
"exec failed",
Expand Down
2 changes: 1 addition & 1 deletion ee/tables/crowdstrike/falconctl/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func TestOptionRestrictions(t *testing.T) {
}
}

func noopExec(ctx context.Context, slogger *slog.Logger, _ int, _ allowedcmd.AllowedCommand, args []string, _ bool, _ ...tablehelpers.ExecOps) ([]byte, error) {
func noopExec(ctx context.Context, slogger *slog.Logger, _ int, _ allowedcmd.AllowedCommand, args []string, _ ...tablehelpers.ExecOps) ([]byte, error) {
slogger.Log(ctx, slog.LevelInfo, "exec-in-test", "args", strings.Join(args, " "))
return []byte{}, nil
}
2 changes: 1 addition & 1 deletion ee/tables/cryptsetup/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (t *Table) generate(ctx context.Context, queryContext table.QueryContext) (
}

for _, name := range requestedNames {
output, err := tablehelpers.Exec(ctx, t.slogger, 15, allowedcmd.Cryptsetup, []string{"--readonly", "status", name}, false)
output, err := tablehelpers.RunSimple(ctx, t.slogger, 15, allowedcmd.Cryptsetup, []string{"--readonly", "status", name})
if err != nil {
t.slogger.Log(ctx, slog.LevelDebug,
"error execing for status",
Expand Down
2 changes: 1 addition & 1 deletion ee/tables/dataflattentable/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TablePluginExec(slogger *slog.Logger, tableName string, dataSourceType Data
func (t *Table) generateExec(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
var results []map[string]string

execBytes, err := tablehelpers.Exec(ctx, t.slogger, 50, t.cmdGen, t.execArgs, false)
execBytes, err := tablehelpers.RunSimple(ctx, t.slogger, 50, t.cmdGen, t.execArgs)
if err != nil {
// exec will error if there's no binary, so we never want to record that
if os.IsNotExist(errors.Cause(err)) {
Expand Down
13 changes: 10 additions & 3 deletions ee/tables/dataflattentable/exec_and_parse.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package dataflattentable

import (
"bytes"
"context"
"io"
"log/slog"
"os"
"strings"
Expand Down Expand Up @@ -72,9 +74,14 @@ func (t *execTableV2) generate(ctx context.Context, queryContext table.QueryCont
defer span.End()

var results []map[string]string
var stdout bytes.Buffer
stdErr := io.Discard

execOutput, err := tablehelpers.Exec(ctx, t.slogger, t.timeoutSeconds, t.cmd, t.execArgs, t.includeStderr)
if err != nil {
if t.includeStderr {
stdErr = &stdout
}

if err := tablehelpers.Run(ctx, t.slogger, t.timeoutSeconds, t.cmd, t.execArgs, &stdout, stdErr); err != nil {
// exec will error if there's no binary, so we never want to record that
if os.IsNotExist(errors.Cause(err)) {
return nil, nil
Expand All @@ -96,7 +103,7 @@ func (t *execTableV2) generate(ctx context.Context, queryContext table.QueryCont
flattenOpts = append(flattenOpts, dataflatten.WithDebugLogging())
}

flattened, err := t.flattener.FlattenBytes(execOutput, flattenOpts...)
flattened, err := t.flattener.FlattenBytes(stdout.Bytes(), flattenOpts...)
if err != nil {
t.slogger.Log(ctx, slog.LevelInfo,
"failure flattening output",
Expand Down
2 changes: 1 addition & 1 deletion ee/tables/dev_table_tooling/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (t *Table) generate(ctx context.Context, queryContext table.QueryContext) (
"error": "",
}

if output, err := tablehelpers.Exec(ctx, t.slogger, 30, cmd.bin, cmd.args, false); err != nil {
if output, err := tablehelpers.RunSimple(ctx, t.slogger, 30, cmd.bin, cmd.args); err != nil {
t.slogger.Log(ctx, slog.LevelInfo,
"execution failed",
"name", name,
Expand Down
16 changes: 2 additions & 14 deletions ee/tables/dsim_default_associations/dsim_default_associations.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/kolide/launcher/ee/agent"
"github.com/kolide/launcher/ee/allowedcmd"
Expand Down Expand Up @@ -82,25 +81,14 @@ func (t *Table) execDism(ctx context.Context) ([]byte, error) {
var stdout bytes.Buffer
var stderr bytes.Buffer

ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()

args := []string{"/online", "/Export-DefaultAppAssociations:" + dstFile}

cmd, err := allowedcmd.Dism(ctx, args...)
if err != nil {
return nil, fmt.Errorf("creating command: %w", err)
}
cmd.Dir = dir
cmd.Stdout = &stdout
cmd.Stderr = &stderr

t.slogger.Log(ctx, slog.LevelDebug,
"calling dsim",
"args", cmd.Args,
"args", args,
)

if err := cmd.Run(); err != nil {
if err := tablehelpers.Run(ctx, t.slogger, 30, allowedcmd.Dism, args, &stdout, &stderr, tablehelpers.WithDir(dir)); err != nil {
return nil, fmt.Errorf("calling dism. Got: %s: %w", stderr.String(), err)
}

Expand Down
2 changes: 1 addition & 1 deletion ee/tables/filevault/filevault.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TablePlugin(slogger *slog.Logger) *table.Plugin {
}

func (t *Table) generate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {
output, err := tablehelpers.Exec(ctx, t.slogger, 10, allowedcmd.Fdesetup, []string{"status"}, false)
output, err := tablehelpers.RunSimple(ctx, t.slogger, 10, allowedcmd.Fdesetup, []string{"status"})
if err != nil {
t.slogger.Log(ctx, slog.LevelInfo,
"fdesetup failed",
Expand Down
17 changes: 2 additions & 15 deletions ee/tables/firmwarepasswd/firmwarepasswd.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import (
"log/slog"
"os"
"strings"
"time"

"github.com/kolide/launcher/ee/agent"
"github.com/kolide/launcher/ee/allowedcmd"
"github.com/kolide/launcher/ee/tables/tablehelpers"
"github.com/osquery/osquery-go/plugin/table"
)

Expand Down Expand Up @@ -91,14 +91,6 @@ func (t *Table) generate(ctx context.Context, queryContext table.QueryContext) (
}

func (t *Table) runFirmwarepasswd(ctx context.Context, subcommand string, output *bytes.Buffer) error {
ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
defer cancel()

cmd, err := allowedcmd.Firmwarepasswd(ctx, subcommand)
if err != nil {
return fmt.Errorf("creating command: %w", err)
}

dir, err := agent.MkdirTemp("osq-firmwarepasswd")
if err != nil {
return fmt.Errorf("mktemp: %w", err)
Expand All @@ -109,14 +101,9 @@ func (t *Table) runFirmwarepasswd(ctx context.Context, subcommand string, output
return fmt.Errorf("chmod: %w", err)
}

cmd.Dir = dir

stderr := new(bytes.Buffer)
cmd.Stderr = stderr

cmd.Stdout = output

if err := cmd.Run(); err != nil {
if err := tablehelpers.Run(ctx, t.slogger, 1, allowedcmd.Firmwarepasswd, []string{subcommand}, output, stderr, tablehelpers.WithDir(dir)); err != nil {
t.slogger.Log(ctx, slog.LevelDebug,
"error running firmwarepasswd",
"stderr", strings.TrimSpace(stderr.String()),
Expand Down
58 changes: 11 additions & 47 deletions ee/tables/gsettings/gsettings.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ import (
"log/slog"
"os"
"os/user"
"strconv"
"strings"
"syscall"
"time"

"github.com/kolide/launcher/ee/agent"
"github.com/kolide/launcher/ee/allowedcmd"
Expand All @@ -26,7 +23,7 @@ import (

const allowedCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-."

type gsettingsExecer func(ctx context.Context, username string, buf *bytes.Buffer) error
type gsettingsExecer func(ctx context.Context, slogger *slog.Logger, username string, buf *bytes.Buffer) error

type GsettingsValues struct {
slogger *slog.Logger
Expand Down Expand Up @@ -61,7 +58,7 @@ func (t *GsettingsValues) generate(ctx context.Context, queryContext table.Query
for _, username := range users {
var output bytes.Buffer

err := t.getBytes(ctx, username, &output)
err := t.getBytes(ctx, t.slogger, username, &output)
if err != nil {
t.slogger.Log(ctx, slog.LevelInfo,
"error getting bytes for user",
Expand All @@ -80,46 +77,12 @@ func (t *GsettingsValues) generate(ctx context.Context, queryContext table.Query

// execGsettings writes the output of running 'gsettings' command into the
// supplied bytes buffer
func execGsettings(ctx context.Context, username string, buf *bytes.Buffer) error {
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()

func execGsettings(ctx context.Context, slogger *slog.Logger, username string, buf *bytes.Buffer) error {
u, err := user.Lookup(username)
if err != nil {
return fmt.Errorf("finding user by username '%s': %w", username, err)
}

cmd, err := allowedcmd.Gsettings(ctx, "list-recursively")
if err != nil {
return fmt.Errorf("creating gsettings command: %w", err)
}

// set the HOME for the the cmd so that gsettings is exec'd properly as the
// new user.
cmd.Env = append(cmd.Env, fmt.Sprintf("HOME=%s", u.HomeDir))

// Check if the supplied UID is that of the current user
currentUser, err := user.Current()
if err != nil {
return fmt.Errorf("checking current user uid: %w", err)
}

if u.Uid != currentUser.Uid {
uid, err := strconv.ParseInt(u.Uid, 10, 32)
if err != nil {
return fmt.Errorf("converting uid from string to int: %w", err)
}
gid, err := strconv.ParseInt(u.Gid, 10, 32)
if err != nil {
return fmt.Errorf("converting gid from string to int: %w", err)
}
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Credential = &syscall.Credential{
Uid: uint32(uid),
Gid: uint32(gid),
}
}

dir, err := agent.MkdirTemp("osq-gsettings")
if err != nil {
return fmt.Errorf("mktemp: %w", err)
Expand All @@ -132,14 +95,15 @@ func execGsettings(ctx context.Context, username string, buf *bytes.Buffer) erro
return fmt.Errorf("chmod: %w", err)
}

cmd.Dir = dir
var stderr bytes.Buffer

stderr := new(bytes.Buffer)
cmd.Stderr = stderr
cmd.Stdout = buf

if err := cmd.Run(); err != nil {
return fmt.Errorf("running gsettings, err is: %s: %w", stderr.String(), err)
if err := tablehelpers.Run(ctx, slogger, 2,
allowedcmd.Gsettings, []string{"list-recursively"}, buf, &stderr,
tablehelpers.WithUid(u.Uid),
tablehelpers.WithAppendEnv("HOME", u.HomeDir),
tablehelpers.WithDir(dir),
); err != nil {
return fmt.Errorf("creating gsettings command: %w", err)
}

return nil
Expand Down
3 changes: 2 additions & 1 deletion ee/tables/gsettings/gsettings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package gsettings
import (
"bytes"
"context"
"log/slog"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -49,7 +50,7 @@ func TestGsettingsValues(t *testing.T) {
tt := tt
table := GsettingsValues{
slogger: multislogger.NewNopLogger(),
getBytes: func(ctx context.Context, username string, buf *bytes.Buffer) error {
getBytes: func(ctx context.Context, slogger *slog.Logger, username string, buf *bytes.Buffer) error {
f, err := os.Open(filepath.Join("testdata", tt.filename))
require.NoError(t, err, "opening file %s", tt.filename)
_, err = buf.ReadFrom(f)
Expand Down
19 changes: 4 additions & 15 deletions ee/tables/gsettings/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import (
"context"
"errors"
"fmt"
"io"
"log/slog"
"os"
"strings"
"time"

"github.com/kolide/launcher/ee/agent"
"github.com/kolide/launcher/ee/allowedcmd"
"github.com/kolide/launcher/ee/tables/tablehelpers"
"github.com/kolide/launcher/pkg/log/multislogger"
"github.com/osquery/osquery-go/plugin/table"
)

Expand Down Expand Up @@ -219,21 +220,9 @@ func (t *GsettingsMetadata) getType(ctx context.Context, schema, key, tmpdir str

// execGsettingsCommand should be called with a tmpdir that will be cleaned up.
func execGsettingsCommand(ctx context.Context, args []string, tmpdir string, output *bytes.Buffer) error {
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()

command := args[0]
cmd, err := allowedcmd.Gsettings(ctx, args...)
if err != nil {
return fmt.Errorf("creating gsettings command: %w", err)
}

cmd.Dir = tmpdir
cmd.Stderr = new(bytes.Buffer)
cmd.Stdout = output

if err := cmd.Run(); err != nil {
return fmt.Errorf("running gsettings %s: %w", command, err)
if err := tablehelpers.Run(ctx, multislogger.NewNopLogger(), 3, allowedcmd.Gsettings, args, output, io.Discard, tablehelpers.WithDir(tmpdir)); err != nil {
return fmt.Errorf("execing gsettings: %s: %w", command, err)
}

return nil
Expand Down
Loading
Loading