Skip to content
Draft
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
17 changes: 15 additions & 2 deletions lib/puppet/file_serving/metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,27 @@ class WindowsStat < MetaStat
def initialize(stat, path, source_permissions)
super(stat, source_permissions)
@path = path
raise(ArgumentError, _("Unsupported Windows source permissions option %{source_permissions}") % { source_permissions: source_permissions }) unless @source_permissions_ignore
end

{ :owner => 'S-1-5-32-544',
:group => 'S-1-0-0',
:mode => 0o644 }.each do |method, default_value|
define_method method do
default_value
return default_value if @source_permissions_ignore

begin
Puppet::Util::Windows::Security.send("get_#{method}", @path) || default_value
rescue Puppet::Util::Windows::Error => detail
# Return defaults for files without a DACL (e.g. on non-NTFS volumes).
# ERROR_INVALID_DACL = 1336
return default_value if detail.code == 1336

# Handle a VirtualBox bug where ERROR_INVALID_FUNCTION is returned when
# following a symlink to a volume that is not NTFS. ERROR_INVALID_FUNCTION = 1
return default_value if detail.code == 1 && Puppet.runtime[:facter].value('virtual') == 'virtualbox'

raise
end
end
end
end
Expand Down
46 changes: 38 additions & 8 deletions spec/unit/file_serving/metadata_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,39 @@
describe "WindowsStat", :if => Puppet::Util::Platform.windows? do
include PuppetSpec::Files

it "should return default owner, group and mode when the given path has an invalid DACL (such as a non-NTFS volume)" do
it "should return default owner, group and mode when source_permissions is :ignore" do
path = tmpfile('foo')
FileUtils.touch(path)
stat = Puppet::FileSystem.stat(path)

win_stat = Puppet::FileServing::Metadata::WindowsStat.new(stat, path, :ignore)

expect(Puppet::Util::Windows::Security).not_to receive(:get_owner)
expect(Puppet::Util::Windows::Security).not_to receive(:get_group)
expect(Puppet::Util::Windows::Security).not_to receive(:get_mode)

expect(win_stat.owner).to eq('S-1-5-32-544')
expect(win_stat.group).to eq('S-1-0-0')
expect(win_stat.mode).to eq(0644)
end

it "should read owner, group and mode from Windows security when source_permissions is :use" do
path = tmpfile('foo')
FileUtils.touch(path)
stat = Puppet::FileSystem.stat(path)

allow(Puppet::Util::Windows::Security).to receive(:get_owner).with(path).and_return('S-1-5-21-1-2-3-500')
allow(Puppet::Util::Windows::Security).to receive(:get_group).with(path).and_return('S-1-5-21-1-2-3-513')
allow(Puppet::Util::Windows::Security).to receive(:get_mode).with(path).and_return(0o640)

win_stat = Puppet::FileServing::Metadata::WindowsStat.new(stat, path, :use)

expect(win_stat.owner).to eq('S-1-5-21-1-2-3-500')
expect(win_stat.group).to eq('S-1-5-21-1-2-3-513')
expect(win_stat.mode).to eq(0o640)
end

it "should return default owner, group and mode when the path has an invalid DACL (such as a non-NTFS volume)" do
invalid_error = Puppet::Util::Windows::Error.new('Invalid DACL', 1336)
path = tmpfile('foo')
FileUtils.touch(path)
Expand All @@ -253,26 +285,24 @@
allow(Puppet::Util::Windows::Security).to receive(:get_mode).with(path).and_raise(invalid_error)

stat = Puppet::FileSystem.stat(path)

win_stat = Puppet::FileServing::Metadata::WindowsStat.new(stat, path, :ignore)
win_stat = Puppet::FileServing::Metadata::WindowsStat.new(stat, path, :use)

expect(win_stat.owner).to eq('S-1-5-32-544')
expect(win_stat.group).to eq('S-1-0-0')
expect(win_stat.mode).to eq(0644)
end

it "should still raise errors that are not the result of an 'Invalid DACL'" do
invalid_error = ArgumentError.new('bar')
it "should re-raise errors that are not the result of an 'Invalid DACL'" do
invalid_error = Puppet::Util::Windows::Error.new('Access denied', 5)
path = tmpfile('bar')
FileUtils.touch(path)

allow(Puppet::Util::Windows::Security).to receive(:get_owner).with(path).and_raise(invalid_error)
allow(Puppet::Util::Windows::Security).to receive(:get_group).with(path).and_raise(invalid_error)
allow(Puppet::Util::Windows::Security).to receive(:get_mode).with(path).and_raise(invalid_error)

stat = Puppet::FileSystem.stat(path)
win_stat = Puppet::FileServing::Metadata::WindowsStat.new(stat, path, :use)

expect { Puppet::FileServing::Metadata::WindowsStat.new(stat, path, :use) }.to raise_error("Unsupported Windows source permissions option use")
expect { win_stat.owner }.to raise_error(Puppet::Util::Windows::Error)
end
end

Expand Down