Module: Puppet::Util::Windows::SID

Includes:
Windows::MSVCRT::String, Windows::Memory, Windows::Security
Included in:
AccessControlEntry, Security, SecurityDescriptor
Defined in:
lib/puppet/util/windows/sid.rb

Constant Summary collapse

ERROR_NONE_MAPPED =

missing from Windows::Error

1332
ERROR_INVALID_SID_STRUCTURE =
1337

Instance Method Summary collapse

Instance Method Details

#name_to_sid(name) ⇒ Object

Convert an account name, e.g. ‘Administrators’ into a SID string, e.g. ‘S-1-5-32-544’. The name can be specified as ‘Administrators’, ‘BUILTINAdministrators’, or ‘S-1-5-32-544’, and will return the SID. Returns nil if the account doesn’t exist.



22
23
24
25
26
# File 'lib/puppet/util/windows/sid.rb', line 22

def name_to_sid(name)
  sid = name_to_sid_object(name)

  sid ? sid.to_s : nil
end

#name_to_sid_object(name) ⇒ Object

Convert an account name, e.g. ‘Administrators’ into a SID object, e.g. ‘S-1-5-32-544’. The name can be specified as ‘Administrators’, ‘BUILTINAdministrators’, or ‘S-1-5-32-544’, and will return the SID object. Returns nil if the account doesn’t exist.



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/puppet/util/windows/sid.rb', line 32

def name_to_sid_object(name)
  # Apparently, we accept a symbol..
  name = name.to_s.strip if name

  # if it's in SID string form, convert to user
  parsed_sid = Win32::Security::SID.string_to_sid(name) rescue nil

  parsed_sid ? Win32::Security::SID.new(parsed_sid) : Win32::Security::SID.new(name)
rescue
  nil
end

#octet_string_to_sid_object(bytes) ⇒ Object

Converts an octet string array of bytes to a SID object, e.g. [1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0] is the representation for S-1-5-18, the local ‘SYSTEM’ account. Raises an Error for nil or non-array input.



48
49
50
51
52
53
54
# File 'lib/puppet/util/windows/sid.rb', line 48

def octet_string_to_sid_object(bytes)
  if !bytes || !bytes.respond_to?('pack') || bytes.empty?
    raise Puppet::Util::Windows::Error.new("Octet string must be an array of bytes")
  end

  Win32::Security::SID.new(bytes.pack('C*'))
end

#sid_ptr_to_string(psid) ⇒ Object

Convert a SID pointer to a SID string, e.g. “S-1-5-32-544”.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/puppet/util/windows/sid.rb', line 72

def sid_ptr_to_string(psid)
  sid_buf = 0.chr * 256
  str_ptr = 0.chr * 4

  raise Puppet::Util::Windows::Error.new("Invalid SID") unless IsValidSid(psid)

  raise Puppet::Util::Windows::Error.new("Failed to convert binary SID") unless ConvertSidToStringSid(psid, str_ptr)

  begin
    strncpy(sid_buf, str_ptr.unpack('L')[0], sid_buf.size - 1)
    sid_buf[sid_buf.size - 1] = 0.chr
    return sid_buf.strip
  ensure
    LocalFree(str_ptr.unpack('L')[0])
  end
end

#sid_to_name(value) ⇒ Object

Convert a SID string, e.g. “S-1-5-32-544” to a name, e.g. ‘BUILTINAdministrators’. Returns nil if an account for that SID does not exist.



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/puppet/util/windows/sid.rb', line 59

def sid_to_name(value)
  sid = Win32::Security::SID.new(Win32::Security::SID.string_to_sid(value))

  if sid.domain and sid.domain.length > 0
    "#{sid.domain}\\#{sid.}"
  else
    sid.
  end
rescue
  nil
end

#string_to_sid_ptr(string, &block) ⇒ Object

Convert a SID string, e.g. “S-1-5-32-544” to a pointer (containing the address of the binary SID structure). The returned value can be used in Win32 APIs that expect a PSID, e.g. IsValidSid. The account for this SID may or may not exist.



93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/puppet/util/windows/sid.rb', line 93

def string_to_sid_ptr(string, &block)
  sid_buf = 0.chr * 80
  string_addr = [string].pack('p*').unpack('L')[0]

  raise Puppet::Util::Windows::Error.new("Failed to convert string SID: #{string}") unless ConvertStringSidToSid(string_addr, sid_buf)

  sid_ptr = sid_buf.unpack('L')[0]
  begin
    yield sid_ptr
  ensure
    LocalFree(sid_ptr)
  end
end

#valid_sid?(string) ⇒ Boolean

Return true if the string is a valid SID, e.g. “S-1-5-32-544”, false otherwise.

Returns:

  • (Boolean)


108
109
110
111
112
113
114
115
116
# File 'lib/puppet/util/windows/sid.rb', line 108

def valid_sid?(string)
  string_to_sid_ptr(string) { |ptr| true }
rescue Puppet::Util::Windows::Error => e
  if e.code == ERROR_INVALID_SID_STRUCTURE
    false
  else
    raise
  end
end