Lines 554-569
module Util
Link Here
|
554 |
# and specifically handle the platform, which has all sorts of magic. |
554 |
# and specifically handle the platform, which has all sorts of magic. |
555 |
# So, unlike Unix, we don't pre-prep security; we use the default "quite |
555 |
# So, unlike Unix, we don't pre-prep security; we use the default "quite |
556 |
# secure" tempfile permissions instead. Magic happens later. |
556 |
# secure" tempfile permissions instead. Magic happens later. |
557 |
unless Puppet.features.microsoft_windows? |
557 |
if !Puppet.features.microsoft_windows? |
558 |
# Grab the current file mode, and fall back to the defaults. |
558 |
# Grab the current file mode, and fall back to the defaults. |
559 |
stat = file.lstat rescue OpenStruct.new(:mode => default_mode, |
559 |
if file.exist? |
560 |
:uid => Process.euid, |
560 |
stat = file.lstat |
561 |
:gid => Process.egid) |
561 |
tempfile.chown(stat.uid, stat.gid) |
|
|
562 |
effective_mode = stat.mode |
563 |
else |
564 |
effective_mode = default_mode |
565 |
end |
562 |
|
566 |
|
563 |
# We only care about the bottom four slots, which make the real mode, |
567 |
if effective_mode |
564 |
# and not the rest of the platform stat call fluff and stuff. |
568 |
# We only care about the bottom four slots, which make the real mode, |
565 |
tempfile.chmod(stat.mode & 07777) |
569 |
# and not the rest of the platform stat call fluff and stuff. |
566 |
tempfile.chown(stat.uid, stat.gid) |
570 |
tempfile.chmod(effective_mode & 07777) |
|
|
571 |
end |
567 |
end |
572 |
end |
568 |
|
573 |
|
569 |
# OK, now allow the caller to write the content of the file. |
574 |
# OK, now allow the caller to write the content of the file. |
Lines 586-626
module Util
Link Here
|
586 |
tempfile.close |
591 |
tempfile.close |
587 |
|
592 |
|
588 |
if Puppet.features.microsoft_windows? |
593 |
if Puppet.features.microsoft_windows? |
589 |
# This will appropriately clone the file, but only if the file we are |
594 |
# Windows ReplaceFile needs a file to exist, so touch handles this |
590 |
# replacing exists. Which is kind of annoying; thanks Microsoft. |
595 |
if !file.exist? |
591 |
# |
596 |
FileUtils.touch(file.to_s) |
592 |
# So, to avoid getting into an infinite loop we will retry once if the |
597 |
if default_mode |
593 |
# file doesn't exist, but only the once... |
598 |
Puppet::Util::Windows::Security.set_mode(default_mode, file.to_s) |
594 |
have_retried = false |
|
|
595 |
|
596 |
begin |
597 |
# Yes, the arguments are reversed compared to the rename in the rest |
598 |
# of the world. |
599 |
Puppet::Util::Windows::File.replace_file(file, tempfile.path) |
600 |
rescue Puppet::Util::Windows::Error => e |
601 |
# This might race, but there are enough possible cases that there |
602 |
# isn't a good, solid "better" way to do this, and the next call |
603 |
# should fail in the same way anyhow. |
604 |
raise if have_retried or File.exist?(file) |
605 |
have_retried = true |
606 |
|
607 |
# OK, so, we can't replace a file that doesn't exist, so let us put |
608 |
# one in place and set the permissions. Then we can retry and the |
609 |
# magic makes this all work. |
610 |
# |
611 |
# This is the least-worst option for handling Windows, as far as we |
612 |
# can determine. |
613 |
File.open(file, 'a') do |fh| |
614 |
# this space deliberately left empty for auto-close behaviour, |
615 |
# append mode, and not actually changing any of the content. |
616 |
end |
599 |
end |
617 |
|
|
|
618 |
# Set the permissions to what we want. |
619 |
Puppet::Util::Windows::Security.set_mode(default_mode, file.to_s) |
620 |
|
621 |
# ...and finally retry the operation. |
622 |
retry |
623 |
end |
600 |
end |
|
|
601 |
# Yes, the arguments are reversed compared to the rename in the rest |
602 |
# of the world. |
603 |
Puppet::Util::Windows::File.replace_file(file, tempfile.path) |
604 |
|
624 |
else |
605 |
else |
625 |
File.rename(tempfile.path, file) |
606 |
File.rename(tempfile.path, file) |
626 |
end |
607 |
end |