mirror of
https://github.com/inspec/inspec
synced 2024-11-10 23:24:18 +00:00
Modified DarwinGroup to collect all users properly. (#4343)
group resource: Modified DarwinGroup to collect all users properly on macos
This commit is contained in:
commit
95e6bcb317
5 changed files with 59 additions and 10 deletions
|
@ -1,6 +1,8 @@
|
|||
# copyright: 2015, Vulcano Security GmbH
|
||||
|
||||
require "inspec/resource"
|
||||
require "inspec/resources/platform"
|
||||
require "inspec/resources/os"
|
||||
|
||||
module Inspec::Resources
|
||||
class Cmd < Inspec.resource(1)
|
||||
|
|
|
@ -164,22 +164,40 @@ module Inspec::Resources
|
|||
# OSX uses opendirectory for groups, so `/etc/group` may not be fully accurate
|
||||
# This uses `dscacheutil` to get the group info instead of `etc_group`
|
||||
class DarwinGroup < GroupInfo
|
||||
def groups
|
||||
group_info = inspec.command("dscacheutil -q group").stdout.split("\n\n")
|
||||
def runmap(cmd, &blk)
|
||||
hashmap(inspec.command(cmd).stdout.lines, &blk)
|
||||
end
|
||||
|
||||
def hashmap(enum, &blk)
|
||||
enum.map(&blk).to_h
|
||||
end
|
||||
|
||||
def groups
|
||||
group_by_id = runmap("dscl . -list /Groups PrimaryGroupID") { |l| name, id = l.split; [id.to_i, name] }
|
||||
userss = runmap("dscl . -list /Users PrimaryGroupID") { |l| name, id = l.split; [name, id.to_i] }
|
||||
membership = runmap("dscl . -list /Groups GroupMembership") { |l| key, *vs = l.split; [key, vs] }
|
||||
membership.default_proc = ->(h, k) { h[k] = [] }
|
||||
|
||||
users_by_group = hashmap(userss.keys.group_by { |k| userss[k] }) { |k, vs| [group_by_id[k], vs] }
|
||||
users_by_group.each do |name, users|
|
||||
membership[name].concat users
|
||||
end
|
||||
|
||||
group_info = inspec.command("dscacheutil -q group").stdout.split("\n\n").uniq
|
||||
|
||||
groups = []
|
||||
regex = /^([^:]*?)\s*:\s(.*?)\s*$/
|
||||
group_info.each do |data|
|
||||
groups << inspec.parse_config(data, assignment_regex: regex).params
|
||||
groups = group_info.map do |data|
|
||||
inspec.parse_config(data, assignment_regex: regex).params
|
||||
end
|
||||
|
||||
# Convert the `dscacheutil` groups to match `inspec.etc_group.entries`
|
||||
groups.each { |g| g["gid"] = g["gid"].to_i }
|
||||
groups.each do |g|
|
||||
next if g["users"].nil?
|
||||
|
||||
g["members"] = g.delete("users")
|
||||
g["members"].tr!(" ", ",")
|
||||
users = g.delete("users") || ""
|
||||
users = users.split
|
||||
users += Array(users_by_group[g["name"]])
|
||||
g["members"] = users
|
||||
g["members"].sort.join ","
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,6 +33,7 @@ module Inspec
|
|||
extend Forwardable
|
||||
|
||||
attr_reader :backend, :rules
|
||||
attr_accessor :target_profiles
|
||||
|
||||
def attributes
|
||||
Inspec.deprecate(:rename_attributes_to_inputs, "Don't call runner.attributes, call runner.inputs")
|
||||
|
|
|
@ -23,6 +23,13 @@ if ENV["CI_ENABLE_COVERAGE"]
|
|||
end
|
||||
end
|
||||
|
||||
module Minitest::Guard
|
||||
# TODO: push up to minitest
|
||||
def osx?(platform = RUBY_PLATFORM)
|
||||
/darwin/ =~ platform
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Do not add any other code from here until the end of this code
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
require "helper"
|
||||
require "inspec/resource"
|
||||
require "inspec/resources/groups"
|
||||
|
||||
describe "Inspec::Resources::Group" do
|
||||
|
@ -37,6 +36,28 @@ describe "Inspec::Resources::Group" do
|
|||
_(resource.gid).must_equal 0
|
||||
end
|
||||
|
||||
def unmock(&blk)
|
||||
require "fetchers/mock"
|
||||
require "inspec/runner"
|
||||
|
||||
# TODO: there is WAY too much magic going on in here
|
||||
runner = Inspec::Runner.new
|
||||
runner.add_target("inspec.yml" => "name: inspec-shell")
|
||||
profile = runner.target_profiles.first
|
||||
ctx = profile.runner_context
|
||||
|
||||
ctx.load blk
|
||||
end
|
||||
|
||||
if osx?
|
||||
it "actually verifies group on mac" do
|
||||
resource = unmock { group "staff" }
|
||||
_(resource.exists?).must_equal true
|
||||
_(resource.members).must_include "root"
|
||||
_(resource.members).must_include ENV["LOGNAME"]
|
||||
end
|
||||
end
|
||||
|
||||
# freebsd
|
||||
it "verify group on freebsd" do
|
||||
resource = MockLoader.new(:freebsd10).load_resource("group", "root")
|
||||
|
|
Loading…
Reference in a new issue