go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/file.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package resources
     5  
     6  import (
     7  	"errors"
     8  	"os"
     9  	"path"
    10  
    11  	"github.com/spf13/afero"
    12  	"go.mondoo.com/cnquery/llx"
    13  	"go.mondoo.com/cnquery/providers-sdk/v1/plugin"
    14  	"go.mondoo.com/cnquery/providers-sdk/v1/resources"
    15  	"go.mondoo.com/cnquery/providers/os/connection/shared"
    16  )
    17  
    18  func (s *mqlFile) id() (string, error) {
    19  	return s.Path.Data, nil
    20  }
    21  
    22  func (s *mqlFile) content(path string, exists bool) (string, error) {
    23  	if !exists {
    24  		return "", resources.NotFoundError{Resource: "file", ID: path}
    25  	}
    26  
    27  	conn := s.MqlRuntime.Connection.(shared.Connection)
    28  	afs := &afero.Afero{Fs: conn.FileSystem()}
    29  	res, err := afs.ReadFile(path)
    30  	return string(res), err
    31  }
    32  
    33  func (s *mqlFile) stat() error {
    34  	conn := s.MqlRuntime.Connection.(shared.Connection)
    35  	stat, err := conn.FileInfo(s.Path.Data)
    36  	if err != nil {
    37  		return err
    38  	}
    39  
    40  	mode := stat.Mode.UnixMode()
    41  	res, err := CreateResource(s.MqlRuntime, "file.permissions", map[string]*llx.RawData{
    42  		"mode":             llx.IntData(int64(uint32(mode) & 0o7777)),
    43  		"user_readable":    llx.BoolData(stat.Mode.UserReadable()),
    44  		"user_writeable":   llx.BoolData(stat.Mode.UserWriteable()),
    45  		"user_executable":  llx.BoolData(stat.Mode.UserExecutable()),
    46  		"group_readable":   llx.BoolData(stat.Mode.GroupReadable()),
    47  		"group_writeable":  llx.BoolData(stat.Mode.GroupWriteable()),
    48  		"group_executable": llx.BoolData(stat.Mode.GroupExecutable()),
    49  		"other_readable":   llx.BoolData(stat.Mode.OtherReadable()),
    50  		"other_writeable":  llx.BoolData(stat.Mode.OtherWriteable()),
    51  		"other_executable": llx.BoolData(stat.Mode.OtherExecutable()),
    52  		"suid":             llx.BoolData(stat.Mode.Suid()),
    53  		"sgid":             llx.BoolData(stat.Mode.Sgid()),
    54  		"sticky":           llx.BoolData(stat.Mode.Sticky()),
    55  		"isDirectory":      llx.BoolData(stat.Mode.IsDir()),
    56  		"isFile":           llx.BoolData(stat.Mode.IsRegular()),
    57  		"isSymlink":        llx.BoolData(stat.Mode.FileMode&os.ModeSymlink != 0),
    58  	})
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	s.Permissions = plugin.TValue[*mqlFilePermissions]{
    64  		Data:  res.(*mqlFilePermissions),
    65  		State: plugin.StateIsSet,
    66  	}
    67  
    68  	s.Size = plugin.TValue[int64]{
    69  		Data:  stat.Size,
    70  		State: plugin.StateIsSet,
    71  	}
    72  
    73  	raw, err := CreateResource(s.MqlRuntime, "users", nil)
    74  	if err != nil {
    75  		return errors.New("cannot get users info for file: " + err.Error())
    76  	}
    77  	users := raw.(*mqlUsers)
    78  
    79  	user, err := users.findID(stat.Uid)
    80  	if err != nil {
    81  		return err
    82  	}
    83  
    84  	s.User = plugin.TValue[*mqlUser]{
    85  		Data:  user,
    86  		State: plugin.StateIsSet,
    87  	}
    88  
    89  	raw, err = CreateResource(s.MqlRuntime, "groups", nil)
    90  	if err != nil {
    91  		return errors.New("cannot get groups info for file: " + err.Error())
    92  	}
    93  	groups := raw.(*mqlGroups)
    94  
    95  	group, err := groups.findID(stat.Gid)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	s.Group = plugin.TValue[*mqlGroup]{
   101  		Data:  group,
   102  		State: plugin.StateIsSet,
   103  	}
   104  
   105  	return nil
   106  }
   107  
   108  func (s *mqlFile) size(path string) (int64, error) {
   109  	return 0, s.stat()
   110  }
   111  
   112  func (s *mqlFile) permissions(path string) (*mqlFilePermissions, error) {
   113  	return nil, s.stat()
   114  }
   115  
   116  func (s *mqlFile) user() (*mqlUser, error) {
   117  	return nil, s.stat()
   118  }
   119  
   120  func (s *mqlFile) group() (*mqlGroup, error) {
   121  	return nil, s.stat()
   122  }
   123  
   124  func (s *mqlFile) empty(path string) (bool, error) {
   125  	conn := s.MqlRuntime.Connection.(shared.Connection)
   126  	afs := &afero.Afero{Fs: conn.FileSystem()}
   127  	return afs.IsEmpty(path)
   128  }
   129  
   130  func (s *mqlFile) basename(fullPath string) (string, error) {
   131  	return path.Base(fullPath), nil
   132  }
   133  
   134  func (s *mqlFile) dirname(fullPath string) (string, error) {
   135  	return path.Dir(fullPath), nil
   136  }
   137  
   138  func (s *mqlFile) exists(path string) (bool, error) {
   139  	conn := s.MqlRuntime.Connection.(shared.Connection)
   140  	afs := &afero.Afero{Fs: conn.FileSystem()}
   141  	return afs.Exists(path)
   142  }
   143  
   144  func (l *mqlFilePermissions) id() (string, error) {
   145  	res := []byte("----------")
   146  
   147  	if l.IsDirectory.Data {
   148  		res[0] = 'd'
   149  	} else if l.IsSymlink.Data {
   150  		res[0] = 'l'
   151  	}
   152  
   153  	if l.User_readable.Data {
   154  		res[1] = 'r'
   155  	}
   156  	if l.User_writeable.Data {
   157  		res[2] = 'w'
   158  	}
   159  	if l.User_executable.Data {
   160  		res[3] = 'x'
   161  		if l.Suid.Data {
   162  			res[3] = 's'
   163  		}
   164  	} else {
   165  		if l.Suid.Data {
   166  			res[3] = 'S'
   167  		}
   168  	}
   169  
   170  	if l.Group_readable.Data {
   171  		res[4] = 'r'
   172  	}
   173  	if l.Group_writeable.Data {
   174  		res[5] = 'w'
   175  	}
   176  	if l.Group_executable.Data {
   177  		res[6] = 'x'
   178  		if l.Sgid.Data {
   179  			res[6] = 's'
   180  		}
   181  	} else {
   182  		if l.Sgid.Data {
   183  			res[6] = 'S'
   184  		}
   185  	}
   186  
   187  	if l.Other_readable.Data {
   188  		res[7] = 'r'
   189  	}
   190  	if l.Other_writeable.Data {
   191  		res[8] = 'w'
   192  	}
   193  	if l.Other_executable.Data {
   194  		res[9] = 'x'
   195  		if l.Sticky.Data {
   196  			res[9] = 't'
   197  		}
   198  	} else {
   199  		if l.Sticky.Data {
   200  			res[9] = 'T'
   201  		}
   202  	}
   203  
   204  	return string(res), nil
   205  }
   206  
   207  func (l *mqlFilePermissions) string() (string, error) {
   208  	return l.__id, nil
   209  }