go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/group.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package resources 5 6 import ( 7 "errors" 8 "strconv" 9 "sync" 10 11 "go.mondoo.com/cnquery/llx" 12 "go.mondoo.com/cnquery/providers/os/connection/shared" 13 "go.mondoo.com/cnquery/providers/os/resources/groups" 14 ) 15 16 type mqlGroupInternal struct { 17 membersArr []string 18 } 19 20 func (x *mqlGroup) id() (string, error) { 21 var id string 22 if len(x.Sid.Data) > 0 { 23 id = x.Sid.Data 24 } else { 25 id = strconv.FormatInt(x.Gid.Data, 10) 26 } 27 28 return "group/" + id + "/" + x.Name.Data, nil 29 } 30 31 func (x *mqlGroup) members() ([]interface{}, error) { 32 raw, err := CreateResource(x.MqlRuntime, "users", nil) 33 if err != nil { 34 return nil, errors.New("cannot get users info for group: " + err.Error()) 35 } 36 users := raw.(*mqlUsers) 37 38 if err := users.refreshCache(nil); err != nil { 39 return nil, err 40 } 41 42 res := make([]interface{}, len(x.membersArr)) 43 for i, name := range x.membersArr { 44 res[i] = users.usersByName[name] 45 } 46 47 return res, nil 48 } 49 50 type mqlGroupsInternal struct { 51 lock sync.Mutex 52 groupsByID map[int64]*mqlGroup 53 } 54 55 func (x *mqlGroups) list() ([]interface{}, error) { 56 x.lock.Lock() 57 defer x.lock.Unlock() 58 59 // in the unlikely case that we get called twice into the same method, 60 // any subsequent calls are locked until user detection finishes; at this point 61 // we only need to return a non-nil error field and it will pull the data from cache 62 if x.groupsByID != nil { 63 return nil, nil 64 } 65 x.groupsByID = map[int64]*mqlGroup{} 66 67 conn := x.MqlRuntime.Connection.(shared.Connection) 68 gm, err := groups.ResolveManager(conn) 69 if gm == nil || err != nil { 70 return nil, errors.New("cannot find groups manager") 71 } 72 73 groups, err := gm.List() 74 if err != nil { 75 return nil, errors.New("could not retrieve groups list") 76 } 77 78 var res []interface{} 79 for i := range groups { 80 group := groups[i] 81 nu, err := CreateResource(x.MqlRuntime, "group", map[string]*llx.RawData{ 82 "name": llx.StringData(group.Name), 83 "gid": llx.IntData(group.Gid), 84 "sid": llx.StringData(group.Sid), 85 }) 86 if err != nil { 87 return nil, err 88 } 89 90 res = append(res, nu) 91 92 g := nu.(*mqlGroup) 93 g.membersArr = group.Members 94 x.groupsByID[g.Gid.Data] = g 95 } 96 97 return res, nil 98 } 99 100 func (x *mqlGroups) findID(id int64) (*mqlGroup, error) { 101 if x := x.GetList(); x.Error != nil { 102 return nil, x.Error 103 } 104 105 res, ok := x.mqlGroupsInternal.groupsByID[id] 106 if !ok { 107 return nil, errors.New("cannot find group for uid " + strconv.Itoa(int(id))) 108 } 109 return res, nil 110 }