Class: Win32::Security::ACL

Inherits:
Object
  • Object
show all
Extended by:
Windows::Security::Functions
Includes:
Windows::Security::Constants, Windows::Security::Functions, Windows::Security::Structs
Defined in:
lib/win32/security/acl.rb

Overview

The ACL class encapsulates an Access Control List.

Constant Summary collapse

VERSION =

The version of the Win32::Security::ACL class.

'0.2.1'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(size = 1024, revision = ACL_REVISION) ⇒ ACL

Creates and returns a new Win32::Security::ACL object. This object encapsulates an ACL structure, including a binary representation of the ACL itself, and the revision information.



27
28
29
30
31
32
33
34
35
36
# File 'lib/win32/security/acl.rb', line 27

def initialize(size = 1024, revision = ACL_REVISION)
  acl = ACL_STRUCT.new

  unless InitializeAcl(acl, size, revision)
    FFI.raise_windows_error('InitializeAcl')
  end

  @acl = acl
  @revision = revision
end

Instance Attribute Details

#aclObject (readonly)

The underlying ACL structure.



18
19
20
# File 'lib/win32/security/acl.rb', line 18

def acl
  @acl
end

#revisionObject

The revision level.



21
22
23
# File 'lib/win32/security/acl.rb', line 21

def revision
  @revision
end

Instance Method Details

#ace_countObject

Returns the number of ACE’s in the ACL object.



40
41
42
43
44
45
46
47
48
# File 'lib/win32/security/acl.rb', line 40

def ace_count
  info = ACL_SIZE_INFORMATION.new

  unless GetAclInformation(@acl, info, info.size, AclSizeInformation)
    FFI.raise_windows_error('GetAclInformation')
  end

  info[:AceCount]
end

#add_access_allowed_ace(sid = nil, mask = 0, flags = nil) ⇒ Object

Adds an access allowed ACE to the given sid, which can be a Win32::Security::SID object or a plain user or group name. If no sid is provided then the owner of the current process is used.

The mask is a bitwise OR’d value of access rights.

The flags argument can be anyone of the following constants.

  • OBJECT_INHERIT_ACE

  • CONTAINER_INHERIT_ACE

  • NO_PROPAGATE_INHERIT_ACE

  • INHERIT_ONLY_ACE

  • INHERITED_ACE

Example:

acl = Win32::Security::ACL.new
acl.add_access_allowed_ace('some_user', GENERIC_READ | GENERIC_WRITE)


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/win32/security/acl.rb', line 82

def add_access_allowed_ace(sid=nil, mask=0, flags=nil)
  if sid.is_a?(Win32::Security::SID)
    sid = sid.sid
  else
    sid = Win32::Security::SID.new(sid).sid
  end

  if flags
    unless AddAccessAllowedAceEx(@acl, @revision, flags, mask, sid)
      FFI.raise_windows_error('AddAccessAllowedAceEx')
    end
  else
    unless AddAccessAllowedAce(@acl, @revision, mask, sid)
      FFI.raise_windows_error('AddAccessAllowedAce')
    end
  end

  sid
end

#add_access_denied_ace(sid = nil, mask = 0, flags = nil) ⇒ Object

Adds an access denied ACE to the given sid, which can be a Win32::Security::SID object ora plain user or group name. If no sid is provided then the owner of the current process is used.

The mask is the bitwise OR’d value of access rights.

The flags argument can be any one of the following constants:

  • OBJECT_INHERIT_ACE

  • CONTAINER_INHERIT_ACE

  • NO_PROPAGATE_INHERIT_ACE

  • INHERIT_ONLY_ACE

  • INHERITED_ACE



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/win32/security/acl.rb', line 116

def add_access_denied_ace(sid=nil, mask=0, flags=nil)
  if sid.is_a?(Win32::Security::SID)
    sid = sid.sid
  else
    sid = Win32::Security::SID.new(sid).sid
  end

  if flags
    unless AddAccessDeniedAceEx(@acl, @revision, flags, mask, sid)
      FFI.raise_windows_error('AddAccessDeniedAceEx')
    end
  else
    unless AddAccessDeniedAce(@acl, @revision, mask, sid)
      FFI.raise_windows_error('AddAccessDeniedAce')
    end
  end
end

#add_ace(ace, index = MAXDWORD) ⇒ Object

Adds an ACE to the ACL object with the given revision at index or the end of the chain if no index is specified.

Returns the index if successful. – This won’t work until we implement the ACE class.



141
142
143
144
145
146
147
# File 'lib/win32/security/acl.rb', line 141

def add_ace(ace, index=MAXDWORD)
  unless AddAce(@acl, @revision, index, ace, ace.length)
    FFI.raise_windows_error('AddAce')
  end

  index
end

#byte_infoObject

Returns a two element array that consists of the bytes in use and bytes free for the ACL.



53
54
55
56
57
58
59
60
61
# File 'lib/win32/security/acl.rb', line 53

def byte_info
  info = ACL_SIZE_INFORMATION.new

  unless GetAclInformation(@acl, info, info.size, AclSizeInformation)
    FFI.raise_windows_error('GetAclInformation')
  end

  [info[:AclBytesInUse], info[:AclBytesFree]]
end

#delete_ace(index = MAXDWORD) ⇒ Object

Deletes an ACE from the ACL object at index, or from the end of the chain if no index is specified.

Returns the index if successful.



154
155
156
157
158
159
160
# File 'lib/win32/security/acl.rb', line 154

def delete_ace(index=MAXDWORD)
  unless DeleteAce(@acl, index)
    FFI.raise_windows_error('DeleteAce')
  end

  index
end

#find_ace(index = nil, raw = false) ⇒ Object

Finds and returns an ACE object for the ACL at the given index. If no index is provided, then it returns an ACE object that corresponds to the first free byte of the ACL.

If raw is true, it will return an ACCESS_GENERIC_ACE struct, an FFI object that you can then access directly.



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/win32/security/acl.rb', line 169

def find_ace(index = nil, raw = false)
  result = nil

  FFI::MemoryPointer.new(:pointer) do |pptr|
    if index.nil?
      unless FindFirstFreeAce(@acl, pptr)
        FFI.raise_windows_error('FindFirstFreeAce')
      end
    else
      unless GetAce(@acl, index, pptr)
        FFI.raise_windows_error('GetAce')
      end
    end

    # There's no way to know what type of ACE it is at this point as far
    # as I know, so we use a generic struct and use the AceType to figure
    # it out later, or the users can.
    ace = ACCESS_GENERIC_ACE.new(pptr.read_pointer)

    if raw
      result = ace
    else
      result = ACE.new(ace[:Mask], ace[:Header][:AceType], ace[:Header][:AceFlags])
    end
  end

  result
end

#valid?Boolean

Returns whether or not the ACL is a valid ACL.

Returns:

  • (Boolean)


219
220
221
# File 'lib/win32/security/acl.rb', line 219

def valid?
  IsValidAcl(@acl)
end