lib/win32/security/acl.rb in win32-security-0.3.1 vs lib/win32/security/acl.rb in win32-security-0.3.2
- old
+ new
@@ -1,224 +1,224 @@
-# The Win32 module serves as a namespace only.
-module Win32
-
- # The Security class serves as a toplevel class namespace.
- class Security
-
- # The ACL class encapsulates an Access Control List.
- class ACL
- include Windows::Security::Constants
- include Windows::Security::Functions
- include Windows::Security::Structs
- extend Windows::Security::Functions
-
- # The version of the Win32::Security::ACL class.
- VERSION = '0.2.0'
-
- # The underlying ACL structure.
- attr_reader :acl
-
- # The revision level.
- attr_reader :revision
-
- # 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.
- #
- def initialize(size = 1024, revision = ACL_REVISION)
- acl = ACL_STRUCT.new
-
- unless InitializeAcl(acl, size, revision)
- raise SystemCallError.new("InitializeAcl", FFI.errno)
- end
-
- @acl = acl
- @revision = revision
- end
-
- # Returns the number of ACE's in the ACL object.
- #
- def ace_count
- info = ACL_SIZE_INFORMATION.new
-
- unless GetAclInformation(@acl, info, info.size, AclSizeInformation)
- raise SystemCallError.new("GetAclInformation", FFI.errno)
- end
-
- info[:AceCount]
- end
-
- # Returns a two element array that consists of the bytes in use and
- # bytes free for the ACL.
- #
- def byte_info
- info = ACL_SIZE_INFORMATION.new
-
- unless GetAclInformation(@acl, info, info.size, AclSizeInformation)
- raise SystemCallError.new("GetAclInformation", FFI.errno)
- end
-
- [info[:AclBytesInUse], info[:AclBytesFree]]
- end
-
- # 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)
- #
- 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)
- raise SystemCallError.new("AddAccessAllowedAceEx", FFI.errno)
- end
- else
- unless AddAccessAllowedAce(@acl, @revision, mask, sid)
- raise SystemCallError.new("AddAccessAllowedAce", FFI.errno)
- end
- end
-
- sid
- end
-
- # 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
- #
- 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)
- raise SystemCallError.new("AddAccessDeniedAceEx", FFI.errno)
- end
- else
- unless AddAccessDeniedAce(@acl, @revision, mask, sid)
- raise SystemCallError.new("AddAccessDeniedAce", FFI.errno)
- end
- end
- end
-
- # 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.
- #
- def add_ace(ace, index=MAXDWORD)
- unless AddAce(@acl, @revision, index, ace, ace.length)
- raise SystemCallError.new("AddAce", FFI.errno)
- end
-
- index
- end
-
- # 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.
- #
- def delete_ace(index=MAXDWORD)
- unless DeleteAce(@acl, index)
- raise SystemCallError.new("DeleteAce", FFI.errno)
- end
-
- index
- end
-
- # 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.
- #
- def find_ace(index = nil, raw = false)
- result = nil
-
- FFI::MemoryPointer.new(:pointer) do |pptr|
- if index.nil?
- unless FindFirstFreeAce(@acl, pptr)
- raise SystemCallError.new("FindFirstFreeAce", FFI.errno)
- end
- else
- unless GetAce(@acl, index, pptr)
- raise SystemCallError.new("GetAce", FFI.errno)
- 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
-
- # Sets the revision information level, where the +revision_level+
- # can be ACL_REVISION1, ACL_REVISION2, ACL_REVISION3 or ACL_REVISION4.
- #
- # Returns the revision level if successful.
- #
- def revision=(revision_level)
- FFI::MemoryPointer.new(:ulong) do |buf|
- buf.write_ulong(revision_level)
-
- unless SetAclInformation(@acl, buf, buf.size, AclRevisionInformation)
- raise SystemCallError.new("SetAclInformation", FFI.errno)
- end
- end
-
- @revision = revision_level
-
- revision_level
- end
-
- # Returns whether or not the ACL is a valid ACL.
- #
- def valid?
- IsValidAcl(@acl)
- end
- end
- end
-end
+# The Win32 module serves as a namespace only.
+module Win32
+
+ # The Security class serves as a toplevel class namespace.
+ class Security
+
+ # The ACL class encapsulates an Access Control List.
+ class ACL
+ include Windows::Security::Constants
+ include Windows::Security::Functions
+ include Windows::Security::Structs
+ extend Windows::Security::Functions
+
+ # The version of the Win32::Security::ACL class.
+ VERSION = '0.2.0'
+
+ # The underlying ACL structure.
+ attr_reader :acl
+
+ # The revision level.
+ attr_reader :revision
+
+ # 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.
+ #
+ def initialize(size = 1024, revision = ACL_REVISION)
+ acl = ACL_STRUCT.new
+
+ unless InitializeAcl(acl, size, revision)
+ raise SystemCallError.new("InitializeAcl", FFI.errno)
+ end
+
+ @acl = acl
+ @revision = revision
+ end
+
+ # Returns the number of ACE's in the ACL object.
+ #
+ def ace_count
+ info = ACL_SIZE_INFORMATION.new
+
+ unless GetAclInformation(@acl, info, info.size, AclSizeInformation)
+ raise SystemCallError.new("GetAclInformation", FFI.errno)
+ end
+
+ info[:AceCount]
+ end
+
+ # Returns a two element array that consists of the bytes in use and
+ # bytes free for the ACL.
+ #
+ def byte_info
+ info = ACL_SIZE_INFORMATION.new
+
+ unless GetAclInformation(@acl, info, info.size, AclSizeInformation)
+ raise SystemCallError.new("GetAclInformation", FFI.errno)
+ end
+
+ [info[:AclBytesInUse], info[:AclBytesFree]]
+ end
+
+ # 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)
+ #
+ 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)
+ raise SystemCallError.new("AddAccessAllowedAceEx", FFI.errno)
+ end
+ else
+ unless AddAccessAllowedAce(@acl, @revision, mask, sid)
+ raise SystemCallError.new("AddAccessAllowedAce", FFI.errno)
+ end
+ end
+
+ sid
+ end
+
+ # 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
+ #
+ 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)
+ raise SystemCallError.new("AddAccessDeniedAceEx", FFI.errno)
+ end
+ else
+ unless AddAccessDeniedAce(@acl, @revision, mask, sid)
+ raise SystemCallError.new("AddAccessDeniedAce", FFI.errno)
+ end
+ end
+ end
+
+ # 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.
+ #
+ def add_ace(ace, index=MAXDWORD)
+ unless AddAce(@acl, @revision, index, ace, ace.length)
+ raise SystemCallError.new("AddAce", FFI.errno)
+ end
+
+ index
+ end
+
+ # 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.
+ #
+ def delete_ace(index=MAXDWORD)
+ unless DeleteAce(@acl, index)
+ raise SystemCallError.new("DeleteAce", FFI.errno)
+ end
+
+ index
+ end
+
+ # 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.
+ #
+ def find_ace(index = nil, raw = false)
+ result = nil
+
+ FFI::MemoryPointer.new(:pointer) do |pptr|
+ if index.nil?
+ unless FindFirstFreeAce(@acl, pptr)
+ raise SystemCallError.new("FindFirstFreeAce", FFI.errno)
+ end
+ else
+ unless GetAce(@acl, index, pptr)
+ raise SystemCallError.new("GetAce", FFI.errno)
+ 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
+
+ # Sets the revision information level, where the +revision_level+
+ # can be ACL_REVISION1, ACL_REVISION2, ACL_REVISION3 or ACL_REVISION4.
+ #
+ # Returns the revision level if successful.
+ #
+ def revision=(revision_level)
+ FFI::MemoryPointer.new(:ulong) do |buf|
+ buf.write_ulong(revision_level)
+
+ unless SetAclInformation(@acl, buf, buf.size, AclRevisionInformation)
+ raise SystemCallError.new("SetAclInformation", FFI.errno)
+ end
+ end
+
+ @revision = revision_level
+
+ revision_level
+ end
+
+ # Returns whether or not the ACL is a valid ACL.
+ #
+ def valid?
+ IsValidAcl(@acl)
+ end
+ end
+ end
+end