Method: Puppet::Util::Windows::Security#get_mode

Defined in:
lib/puppet/util/windows/security.rb

#get_mode(path) ⇒ Object

Get the mode of the object referenced by path. The returned integer value represents the POSIX-style read, write, and execute modes for the user, group, and other classes, e.g. 0640. Any user with read access to an object can get the mode. Only a user with the SE_BACKUP_NAME privilege in their process token can get the mode for objects they do not have read access to.



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/puppet/util/windows/security.rb', line 201

def get_mode(path)
  return unless supports_acl?(path)

  well_known_world_sid = Puppet::Util::Windows::SID::Everyone
  well_known_nobody_sid = Puppet::Util::Windows::SID::Nobody
  well_known_system_sid = Puppet::Util::Windows::SID::LocalSystem
  well_known_app_packages_sid = Puppet::Util::Windows::SID::AllAppPackages

  mode = S_ISYSTEM_MISSING

  sd = get_security_descriptor(path)
  sd.dacl.each do |ace|
    next if ace.inherit_only?

    case ace.sid
    when sd.owner
      MASK_TO_MODE.each_pair do |k, v|
        if (ace.mask & k) == k
          mode |= (v << 6)
        end
      end
    when sd.group
      MASK_TO_MODE.each_pair do |k, v|
        if (ace.mask & k) == k
          mode |= (v << 3)
        end
      end
    when well_known_world_sid
      MASK_TO_MODE.each_pair do |k, v|
        if (ace.mask & k) == k
          mode |= (v << 6) | (v << 3) | v
        end
      end
      if File.directory?(path) &&
         (ace.mask & (FILE::FILE_WRITE_DATA | FILE::FILE_EXECUTE | FILE::FILE_DELETE_CHILD)) == (FILE::FILE_WRITE_DATA | FILE::FILE_EXECUTE)
        mode |= S_ISVTX;
      end
    when well_known_nobody_sid
      if (ace.mask & FILE::FILE_APPEND_DATA).nonzero?
        mode |= S_ISVTX
      end
    when well_known_app_packages_sid, well_known_system_sid
      # do nothing
    else
      # puts "Warning, unable to map SID into POSIX mode: #{ace.sid}"
      mode |= S_IEXTRA
    end

    if ace.sid == well_known_system_sid
      mode &= ~S_ISYSTEM_MISSING
    end

    # if owner and group the same, then user and group modes are the OR of both
    if sd.owner == sd.group
      mode |= ((mode & S_IRWXG) << 3) | ((mode & S_IRWXU) >> 3)
      # puts "owner: #{sd.group}, 0x#{ace.mask.to_s(16)}, #{mode.to_s(8)}"
    end
  end

  # puts "get_mode: #{mode.to_s(8)}"
  mode
end