Skip to content

Commit ce0216f

Browse files
authored
Merge pull request #8519 from luchihoratiu/PUP-10898
2 parents a15f2b1 + 0302419 commit ce0216f

File tree

6 files changed

+85
-2
lines changed

6 files changed

+85
-2
lines changed

lib/puppet/file_system/windows.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ def replace_file(path, mode = nil)
128128
end
129129

130130
current_sid = Puppet::Util::Windows::SID.name_to_sid(Puppet::Util::Windows::ADSI::User.current_user_name)
131+
current_sid = Puppet::Util::Windows::SID.name_to_sid(Puppet::Util::Windows::ADSI::User.current_sam_compatible_user_name) unless current_sid
132+
131133
dacl = case mode
132134
when 0644
133135
dacl = secure_dacl(current_sid)

lib/puppet/util/windows/adsi.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,43 @@ def self.current_user_name
504504
user_name
505505
end
506506

507+
# https://docs.microsoft.com/en-us/windows/win32/api/secext/ne-secext-extended_name_format
508+
NameUnknown = 0
509+
NameFullyQualifiedDN = 1
510+
NameSamCompatible = 2
511+
NameDisplay = 3
512+
NameUniqueId = 6
513+
NameCanonical = 7
514+
NameUserPrincipal = 8
515+
NameCanonicalEx = 9
516+
NameServicePrincipal = 10
517+
NameDnsDomain = 12
518+
NameGivenName = 13
519+
NameSurname = 14
520+
521+
def self.current_user_name_with_format(format)
522+
user_name = ''
523+
max_length = 1024
524+
525+
FFI::MemoryPointer.new(:lpwstr, max_length * 2 + 1) do |buffer|
526+
FFI::MemoryPointer.new(:dword, 1) do |buffer_size|
527+
buffer_size.write_dword(max_length + 1)
528+
529+
if GetUserNameExW(format.to_i, buffer, buffer_size) == FFI::WIN32_FALSE
530+
raise Puppet::Util::Windows::Error.new(_("Failed to get user name"), FFI.errno)
531+
end
532+
533+
user_name = buffer.read_wide_string(buffer_size.read_dword).chomp
534+
end
535+
end
536+
537+
user_name
538+
end
539+
540+
def self.current_sam_compatible_user_name
541+
current_user_name_with_format(NameSamCompatible)
542+
end
543+
507544
def self.current_user_sid
508545
Puppet::Util::Windows::SID.name_to_principal(current_user_name)
509546
end
@@ -518,6 +555,15 @@ def self.current_user_sid
518555
ffi_lib :advapi32
519556
attach_function_private :GetUserNameW,
520557
[:lpwstr, :lpdword], :win32_bool
558+
559+
# https://docs.microsoft.com/en-us/windows/win32/api/secext/nf-secext-getusernameexa
560+
# BOOLEAN SEC_ENTRY GetUserNameExA(
561+
# EXTENDED_NAME_FORMAT NameFormat,
562+
# LPSTR lpNameBuffer,
563+
# PULONG nSize
564+
# );type
565+
ffi_lib :secur32
566+
attach_function_private :GetUserNameExW, [:uint16, :lpwstr, :pointer], :win32_bool
521567
end
522568

523569
class UserProfile

lib/puppet/util/windows/sid.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,13 @@ def name_to_principal(name, allow_unresolved = false)
7474
string_to_sid_ptr(name) do |sid_ptr|
7575
raw_sid_bytes = sid_ptr.read_array_of_uchar(get_length_sid(sid_ptr))
7676
end
77-
rescue
77+
rescue => e
78+
Puppet.debug("Could not retrieve raw SID bytes from '#{name}': #{e.message}")
7879
end
7980

8081
raw_sid_bytes ? Principal.lookup_account_sid(raw_sid_bytes) : Principal.lookup_account_name(name)
81-
rescue
82+
rescue => e
83+
Puppet.debug("#{e.message}")
8284
(allow_unresolved && raw_sid_bytes) ? unresolved_principal(name, raw_sid_bytes) : nil
8385
end
8486
module_function :name_to_principal

spec/integration/util/windows/adsi_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,24 @@
5555
end
5656
end
5757
end
58+
59+
describe '.current_user_name_with_format' do
60+
context 'when desired format is NameSamCompatible' do
61+
it 'should get the same user name as the current_user_name method but fully qualified' do
62+
user_name = Puppet::Util::Windows::ADSI::User.current_user_name
63+
fully_qualified_user_name = Puppet::Util::Windows::ADSI::User.current_sam_compatible_user_name
64+
65+
expect(fully_qualified_user_name).to match(/^.+\\#{user_name}$/)
66+
end
67+
68+
it 'should have the same SID as with the current_user_name method' do
69+
user_name = Puppet::Util::Windows::ADSI::User.current_user_name
70+
fully_qualified_user_name = Puppet::Util::Windows::ADSI::User.current_sam_compatible_user_name
71+
72+
expect(Puppet::Util::Windows::SID.name_to_sid(user_name)).to eq(Puppet::Util::Windows::SID.name_to_sid(fully_qualified_user_name))
73+
end
74+
end
75+
end
5876
end
5977

6078
describe Puppet::Util::Windows::ADSI::Group,

spec/unit/file_system_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,15 @@ def increment_counter_in_multiple_processes(file, num_procs, options)
999999
Puppet::FileSystem.replace_file(dest, 0755) { |_| }
10001000
}.to raise_error(ArgumentError, /Only modes 0644, 0640, 0660, and 0440 are allowed/)
10011001
end
1002+
1003+
it 'falls back to fully qualified user name when sid retrieval fails' do
1004+
current_user_sid = Puppet::Util::Windows::SID.name_to_sid(Puppet::Util::Windows::ADSI::User.current_user_name)
1005+
allow(Puppet::Util::Windows::SID).to receive(:name_to_sid).with(Puppet::Util::Windows::ADSI::User.current_user_name).and_return(nil, current_user_sid)
1006+
allow(Puppet::Util::Windows::SID).to receive(:name_to_sid).with(Puppet::Util::Windows::ADSI::User.current_sam_compatible_user_name).and_call_original
1007+
1008+
Puppet::FileSystem.replace_file(dest, 0644) { |f| f.write(content) }
1009+
expects_public_file(dest)
1010+
end
10021011
end
10031012
end
10041013

spec/unit/util/windows/sid_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@
158158
# this works in French Windows, even though the account is really AUTORITE NT\\Syst\u00E8me
159159
expect(subject.name_to_principal('NT AUTHORITY\SYSTEM').sid).to eq(sid)
160160
end
161+
162+
it "should print a debug message on failures" do
163+
expect(Puppet).to receive(:debug).with(/Could not retrieve raw SID bytes from 'NonExistingUser'/)
164+
expect(Puppet).to receive(:debug).with(/No mapping between account names and security IDs was done/)
165+
subject.name_to_principal('NonExistingUser')
166+
end
161167
end
162168

163169
context "#ads_to_principal" do

0 commit comments

Comments
 (0)