func userInGroup(u *user.User, g *Group) (bool, error) { if u.Gid == g.Gid { return true, nil } gid, err := strconv.Atoi(g.Gid) if err != nil { return false, err } nameC := C.CString(u.Username) defer C.free(unsafe.Pointer(nameC)) groupC := C.gid_t(gid) ngroupsC := C.int(0) C.mygetgrouplist(nameC, groupC, nil, &ngroupsC) ngroups := int(ngroupsC) groups := C.malloc(C.size_t(int(unsafe.Sizeof(groupC)) * ngroups)) defer C.free(groups) rv := C.mygetgrouplist(nameC, groupC, (*C.gid_t)(groups), &ngroupsC) if rv == -1 { return false, fmt.Errorf("user: membership of %s in %s: %s", u.Username, g.Name, syscall.Errno(rv)) } ngroups = int(ngroupsC) for i := 0; i < ngroups; i++ { gid := C.group_at(C.int(i), (*C.gid_t)(groups)) if g.Gid == strconv.Itoa(int(gid)) { return true, nil } } return false, nil }
func GetGroupList(u *user.User) ([]string, error) { var members []string gid, err := strconv.Atoi(u.Gid) if err != nil { return nil, err } nameC := C.CString(u.Username) defer C.free(unsafe.Pointer(nameC)) groupC := C.gid_t(gid) ngroupsC := C.int(0) C.mygetgrouplist(nameC, groupC, nil, &ngroupsC) ngroups := int(ngroupsC) groups := C.malloc(C.size_t(int(unsafe.Sizeof(groupC)) * ngroups)) defer C.free(groups) rv := C.mygetgrouplist(nameC, groupC, (*C.gid_t)(groups), &ngroupsC) if rv == -1 { return nil, fmt.Errorf("user: membership of %s in %s: %s", u.Username, u.Gid, syscall.Errno(rv)) } ngroups = int(ngroupsC) for i := 0; i < ngroups; i++ { gid := C.group_at(C.int(i), (*C.gid_t)(groups)) gidS := strconv.Itoa(int(gid)) group, err := LookupGroupID(gidS) if err != nil { return nil, err } members = append(members, group.Name) } return members, nil }
func listGroups(u *User) ([]string, error) { ug, err := strconv.Atoi(u.Gid) if err != nil { return nil, fmt.Errorf("user: list groups for %s: invalid gid %q", u.Username, u.Gid) } userGID := C.gid_t(ug) nameC := C.CString(u.Username) defer C.free(unsafe.Pointer(nameC)) n := C.int(256) gidsC := make([]C.gid_t, n) rv := C.mygetgrouplist(nameC, userGID, &gidsC[0], &n) if rv == -1 { // More than initial buffer, but now n contains the correct size. const maxGroups = 2048 if n > maxGroups { return nil, fmt.Errorf("user: list groups for %s: member of more than %d groups", u.Username, maxGroups) } gidsC = make([]C.gid_t, n) rv := C.mygetgrouplist(nameC, userGID, &gidsC[0], &n) if rv == -1 { return nil, fmt.Errorf("user: list groups for %s failed (changed groups?)", u.Username) } } gidsC = gidsC[:n] gids := make([]string, 0, n) for _, g := range gidsC[:n] { gids = append(gids, strconv.Itoa(int(g))) } return gids, nil }
func getGroupList(name *C.char, userGID C.gid_t, gids *C.gid_t, n *C.int) C.int { return C.mygetgrouplist(name, userGID, gids, n) }