win32-security 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,75 +1,75 @@
1
- # The Win32 module serves as a namespace only.
2
- module Win32
3
-
4
- # The Security class serves as a toplevel class namespace.
5
- class Security
6
-
7
- # The ACE class encapsulates an Access Control Entry, an element within
8
- # an Access Control List.
9
- class ACE
10
- # The version of the Win32::Security::ACE class.
11
- VERSION = '0.1.0'
12
-
13
- # The ACE type, e.g. ACCESS_ALLOWED, ACCESS_DENIED, etc. This is an integer.
14
- attr_accessor :ace_type
15
-
16
- # Standard access rights, e.g. GENERIC_READ, GENERIC_WRITE, etc.
17
- # This is an integer.
18
- attr_accessor :access_mask
19
-
20
- # Bit flags associated with the ACE, e.g. OBJECT_INHERIT_ACE, etc.
21
- # This is an integer.
22
- attr_reader :flags
23
-
24
- # Creates and returns an ACE object.
25
- #
26
- def initialize(access_mask, ace_type, flags)
27
- @access_mask = access_mask
28
- @ace_type = ace_type
29
- @flags = flags
30
- yield self if block_given?
31
- end
32
-
33
- # Returns the type of ace as a string, e.g. "ACCESS_ALLOWED_TYPE_ACE".
34
- #
35
- def ace_type_string
36
- case @ace_type
37
- when 0x0
38
- 'ACCESS_ALLOWED_ACE_TYPE'
39
- when 0x1
40
- 'ACCESS_DENIED_ACE_TYPE'
41
- when 0x2
42
- 'SYSTEM_AUDIT_ACE_TYPE'
43
- when 0x3
44
- 'SYSTEM_ALARM_ACE_TYPE'
45
- when 0x4
46
- 'ACCESS_ALLOWED_COMPOUND_ACE_TYPE'
47
- when 0x5
48
- 'ACCESS_ALLOWED_OBJECT_ACE_TYPE'
49
- when 0x6
50
- 'ACCESS_DENIED_OBJECT_ACE_TYPE'
51
- when 0x7
52
- 'SYSTEM_AUDIT_OBJECT_ACE_TYPE'
53
- when 0x8
54
- 'SYSTEM_ALARM_OBJECT_ACE_TYPE'
55
- when 0x9
56
- 'ACCESS_ALLOWED_CALLBACK_ACE_TYPE'
57
- when 0xA
58
- 'ACCESS_DENIED_CALLBACK_ACE_TYPE'
59
- when 0xB
60
- 'ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE'
61
- when 0xC
62
- 'ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE'
63
- when 0xD
64
- 'SYSTEM_AUDIT_CALLBACK_ACE_TYPE'
65
- when 0xE
66
- 'SYSTEM_ALARM_CALLBACK_ACE_TYPE'
67
- when 0xF
68
- 'SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE'
69
- when 0x10
70
- 'SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE'
71
- end
72
- end
73
- end
74
- end
75
- end
1
+ # The Win32 module serves as a namespace only.
2
+ module Win32
3
+
4
+ # The Security class serves as a toplevel class namespace.
5
+ class Security
6
+
7
+ # The ACE class encapsulates an Access Control Entry, an element within
8
+ # an Access Control List.
9
+ class ACE
10
+ # The version of the Win32::Security::ACE class.
11
+ VERSION = '0.1.0'
12
+
13
+ # The ACE type, e.g. ACCESS_ALLOWED, ACCESS_DENIED, etc. This is an integer.
14
+ attr_accessor :ace_type
15
+
16
+ # Standard access rights, e.g. GENERIC_READ, GENERIC_WRITE, etc.
17
+ # This is an integer.
18
+ attr_accessor :access_mask
19
+
20
+ # Bit flags associated with the ACE, e.g. OBJECT_INHERIT_ACE, etc.
21
+ # This is an integer.
22
+ attr_reader :flags
23
+
24
+ # Creates and returns an ACE object.
25
+ #
26
+ def initialize(access_mask, ace_type, flags)
27
+ @access_mask = access_mask
28
+ @ace_type = ace_type
29
+ @flags = flags
30
+ yield self if block_given?
31
+ end
32
+
33
+ # Returns the type of ace as a string, e.g. "ACCESS_ALLOWED_TYPE_ACE".
34
+ #
35
+ def ace_type_string
36
+ case @ace_type
37
+ when 0x0
38
+ 'ACCESS_ALLOWED_ACE_TYPE'
39
+ when 0x1
40
+ 'ACCESS_DENIED_ACE_TYPE'
41
+ when 0x2
42
+ 'SYSTEM_AUDIT_ACE_TYPE'
43
+ when 0x3
44
+ 'SYSTEM_ALARM_ACE_TYPE'
45
+ when 0x4
46
+ 'ACCESS_ALLOWED_COMPOUND_ACE_TYPE'
47
+ when 0x5
48
+ 'ACCESS_ALLOWED_OBJECT_ACE_TYPE'
49
+ when 0x6
50
+ 'ACCESS_DENIED_OBJECT_ACE_TYPE'
51
+ when 0x7
52
+ 'SYSTEM_AUDIT_OBJECT_ACE_TYPE'
53
+ when 0x8
54
+ 'SYSTEM_ALARM_OBJECT_ACE_TYPE'
55
+ when 0x9
56
+ 'ACCESS_ALLOWED_CALLBACK_ACE_TYPE'
57
+ when 0xA
58
+ 'ACCESS_DENIED_CALLBACK_ACE_TYPE'
59
+ when 0xB
60
+ 'ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE'
61
+ when 0xC
62
+ 'ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE'
63
+ when 0xD
64
+ 'SYSTEM_AUDIT_CALLBACK_ACE_TYPE'
65
+ when 0xE
66
+ 'SYSTEM_ALARM_CALLBACK_ACE_TYPE'
67
+ when 0xF
68
+ 'SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE'
69
+ when 0x10
70
+ 'SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE'
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,224 +1,224 @@
1
- # The Win32 module serves as a namespace only.
2
- module Win32
3
-
4
- # The Security class serves as a toplevel class namespace.
5
- class Security
6
-
7
- # The ACL class encapsulates an Access Control List.
8
- class ACL
9
- include Windows::Security::Constants
10
- include Windows::Security::Functions
11
- include Windows::Security::Structs
12
- extend Windows::Security::Functions
13
-
14
- # The version of the Win32::Security::ACL class.
15
- VERSION = '0.2.0'
16
-
17
- # The underlying ACL structure.
18
- attr_reader :acl
19
-
20
- # The revision level.
21
- attr_reader :revision
22
-
23
- # Creates and returns a new Win32::Security::ACL object. This object
24
- # encapsulates an ACL structure, including a binary representation of
25
- # the ACL itself, and the revision information.
26
- #
27
- def initialize(size = 1024, revision = ACL_REVISION)
28
- acl = ACL_STRUCT.new
29
-
30
- unless InitializeAcl(acl, size, revision)
31
- raise SystemCallError.new("InitializeAcl", FFI.errno)
32
- end
33
-
34
- @acl = acl
35
- @revision = revision
36
- end
37
-
38
- # Returns the number of ACE's in the ACL object.
39
- #
40
- def ace_count
41
- info = ACL_SIZE_INFORMATION.new
42
-
43
- unless GetAclInformation(@acl, info, info.size, AclSizeInformation)
44
- raise SystemCallError.new("GetAclInformation", FFI.errno)
45
- end
46
-
47
- info[:AceCount]
48
- end
49
-
50
- # Returns a two element array that consists of the bytes in use and
51
- # bytes free for the ACL.
52
- #
53
- def byte_info
54
- info = ACL_SIZE_INFORMATION.new
55
-
56
- unless GetAclInformation(@acl, info, info.size, AclSizeInformation)
57
- raise SystemCallError.new("GetAclInformation", FFI.errno)
58
- end
59
-
60
- [info[:AclBytesInUse], info[:AclBytesFree]]
61
- end
62
-
63
- # Adds an access allowed ACE to the given +sid+, which can be a
64
- # Win32::Security::SID object or a plain user or group name. If no
65
- # sid is provided then the owner of the current process is used.
66
- #
67
- # The +mask+ is a bitwise OR'd value of access rights.
68
- #
69
- # The +flags+ argument can be anyone of the following constants.
70
- #
71
- # * OBJECT_INHERIT_ACE
72
- # * CONTAINER_INHERIT_ACE
73
- # * NO_PROPAGATE_INHERIT_ACE
74
- # * INHERIT_ONLY_ACE
75
- # * INHERITED_ACE
76
- #
77
- # Example:
78
- #
79
- # acl = Win32::Security::ACL.new
80
- # acl.add_access_allowed_ace('some_user', GENERIC_READ | GENERIC_WRITE)
81
- #
82
- def add_access_allowed_ace(sid=nil, mask=0, flags=nil)
83
- if sid.is_a?(Win32::Security::SID)
84
- sid = sid.sid
85
- else
86
- sid = Win32::Security::SID.new(sid).sid
87
- end
88
-
89
- if flags
90
- unless AddAccessAllowedAceEx(@acl, @revision, flags, mask, sid)
91
- raise SystemCallError.new("AddAccessAllowedAceEx", FFI.errno)
92
- end
93
- else
94
- unless AddAccessAllowedAce(@acl, @revision, mask, sid)
95
- raise SystemCallError.new("AddAccessAllowedAce", FFI.errno)
96
- end
97
- end
98
-
99
- sid
100
- end
101
-
102
- # Adds an access denied ACE to the given +sid+, which can be a
103
- # Win32::Security::SID object ora plain user or group name. If
104
- # no sid is provided then the owner of the current process is used.
105
- #
106
- # The +mask+ is the bitwise OR'd value of access rights.
107
- #
108
- # The +flags+ argument can be any one of the following constants:
109
- #
110
- # * OBJECT_INHERIT_ACE
111
- # * CONTAINER_INHERIT_ACE
112
- # * NO_PROPAGATE_INHERIT_ACE
113
- # * INHERIT_ONLY_ACE
114
- # * INHERITED_ACE
115
- #
116
- def add_access_denied_ace(sid=nil, mask=0, flags=nil)
117
- if sid.is_a?(Win32::Security::SID)
118
- sid = sid.sid
119
- else
120
- sid = Win32::Security::SID.new(sid).sid
121
- end
122
-
123
- if flags
124
- unless AddAccessDeniedAceEx(@acl, @revision, flags, mask, sid)
125
- raise SystemCallError.new("AddAccessDeniedAceEx", FFI.errno)
126
- end
127
- else
128
- unless AddAccessDeniedAce(@acl, @revision, mask, sid)
129
- raise SystemCallError.new("AddAccessDeniedAce", FFI.errno)
130
- end
131
- end
132
- end
133
-
134
- # Adds an ACE to the ACL object with the given +revision+ at +index+
135
- # or the end of the chain if no index is specified.
136
- #
137
- # Returns the index if successful.
138
- #--
139
- # This won't work until we implement the ACE class.
140
- #
141
- def add_ace(ace, index=MAXDWORD)
142
- unless AddAce(@acl, @revision, index, ace, ace.length)
143
- raise SystemCallError.new("AddAce", FFI.errno)
144
- end
145
-
146
- index
147
- end
148
-
149
- # Deletes an ACE from the ACL object at +index+, or from the end of
150
- # the chain if no index is specified.
151
- #
152
- # Returns the index if successful.
153
- #
154
- def delete_ace(index=MAXDWORD)
155
- unless DeleteAce(@acl, index)
156
- raise SystemCallError.new("DeleteAce", FFI.errno)
157
- end
158
-
159
- index
160
- end
161
-
162
- # Finds and returns an ACE object for the ACL at the given
163
- # +index+. If no index is provided, then it returns an ACE object
164
- # that corresponds to the first free byte of the ACL.
165
- #
166
- # If +raw+ is true, it will return an ACCESS_GENERIC_ACE struct,
167
- # an FFI object that you can then access directly.
168
- #
169
- def find_ace(index = nil, raw = false)
170
- result = nil
171
-
172
- FFI::MemoryPointer.new(:pointer) do |pptr|
173
- if index.nil?
174
- unless FindFirstFreeAce(@acl, pptr)
175
- raise SystemCallError.new("FindFirstFreeAce", FFI.errno)
176
- end
177
- else
178
- unless GetAce(@acl, index, pptr)
179
- raise SystemCallError.new("GetAce", FFI.errno)
180
- end
181
- end
182
-
183
- # There's no way to know what type of ACE it is at this point as far
184
- # as I know, so we use a generic struct and use the AceType to figure
185
- # it out later, or the users can.
186
- ace = ACCESS_GENERIC_ACE.new(pptr.read_pointer)
187
-
188
- if raw
189
- result = ace
190
- else
191
- result = ACE.new(ace[:Mask], ace[:Header][:AceType], ace[:Header][:AceFlags])
192
- end
193
- end
194
-
195
- result
196
- end
197
-
198
- # Sets the revision information level, where the +revision_level+
199
- # can be ACL_REVISION1, ACL_REVISION2, ACL_REVISION3 or ACL_REVISION4.
200
- #
201
- # Returns the revision level if successful.
202
- #
203
- def revision=(revision_level)
204
- FFI::MemoryPointer.new(:ulong) do |buf|
205
- buf.write_ulong(revision_level)
206
-
207
- unless SetAclInformation(@acl, buf, buf.size, AclRevisionInformation)
208
- raise SystemCallError.new("SetAclInformation", FFI.errno)
209
- end
210
- end
211
-
212
- @revision = revision_level
213
-
214
- revision_level
215
- end
216
-
217
- # Returns whether or not the ACL is a valid ACL.
218
- #
219
- def valid?
220
- IsValidAcl(@acl)
221
- end
222
- end
223
- end
224
- end
1
+ # The Win32 module serves as a namespace only.
2
+ module Win32
3
+
4
+ # The Security class serves as a toplevel class namespace.
5
+ class Security
6
+
7
+ # The ACL class encapsulates an Access Control List.
8
+ class ACL
9
+ include Windows::Security::Constants
10
+ include Windows::Security::Functions
11
+ include Windows::Security::Structs
12
+ extend Windows::Security::Functions
13
+
14
+ # The version of the Win32::Security::ACL class.
15
+ VERSION = '0.2.0'
16
+
17
+ # The underlying ACL structure.
18
+ attr_reader :acl
19
+
20
+ # The revision level.
21
+ attr_reader :revision
22
+
23
+ # Creates and returns a new Win32::Security::ACL object. This object
24
+ # encapsulates an ACL structure, including a binary representation of
25
+ # the ACL itself, and the revision information.
26
+ #
27
+ def initialize(size = 1024, revision = ACL_REVISION)
28
+ acl = ACL_STRUCT.new
29
+
30
+ unless InitializeAcl(acl, size, revision)
31
+ raise SystemCallError.new("InitializeAcl", FFI.errno)
32
+ end
33
+
34
+ @acl = acl
35
+ @revision = revision
36
+ end
37
+
38
+ # Returns the number of ACE's in the ACL object.
39
+ #
40
+ def ace_count
41
+ info = ACL_SIZE_INFORMATION.new
42
+
43
+ unless GetAclInformation(@acl, info, info.size, AclSizeInformation)
44
+ raise SystemCallError.new("GetAclInformation", FFI.errno)
45
+ end
46
+
47
+ info[:AceCount]
48
+ end
49
+
50
+ # Returns a two element array that consists of the bytes in use and
51
+ # bytes free for the ACL.
52
+ #
53
+ def byte_info
54
+ info = ACL_SIZE_INFORMATION.new
55
+
56
+ unless GetAclInformation(@acl, info, info.size, AclSizeInformation)
57
+ raise SystemCallError.new("GetAclInformation", FFI.errno)
58
+ end
59
+
60
+ [info[:AclBytesInUse], info[:AclBytesFree]]
61
+ end
62
+
63
+ # Adds an access allowed ACE to the given +sid+, which can be a
64
+ # Win32::Security::SID object or a plain user or group name. If no
65
+ # sid is provided then the owner of the current process is used.
66
+ #
67
+ # The +mask+ is a bitwise OR'd value of access rights.
68
+ #
69
+ # The +flags+ argument can be anyone of the following constants.
70
+ #
71
+ # * OBJECT_INHERIT_ACE
72
+ # * CONTAINER_INHERIT_ACE
73
+ # * NO_PROPAGATE_INHERIT_ACE
74
+ # * INHERIT_ONLY_ACE
75
+ # * INHERITED_ACE
76
+ #
77
+ # Example:
78
+ #
79
+ # acl = Win32::Security::ACL.new
80
+ # acl.add_access_allowed_ace('some_user', GENERIC_READ | GENERIC_WRITE)
81
+ #
82
+ def add_access_allowed_ace(sid=nil, mask=0, flags=nil)
83
+ if sid.is_a?(Win32::Security::SID)
84
+ sid = sid.sid
85
+ else
86
+ sid = Win32::Security::SID.new(sid).sid
87
+ end
88
+
89
+ if flags
90
+ unless AddAccessAllowedAceEx(@acl, @revision, flags, mask, sid)
91
+ raise SystemCallError.new("AddAccessAllowedAceEx", FFI.errno)
92
+ end
93
+ else
94
+ unless AddAccessAllowedAce(@acl, @revision, mask, sid)
95
+ raise SystemCallError.new("AddAccessAllowedAce", FFI.errno)
96
+ end
97
+ end
98
+
99
+ sid
100
+ end
101
+
102
+ # Adds an access denied ACE to the given +sid+, which can be a
103
+ # Win32::Security::SID object ora plain user or group name. If
104
+ # no sid is provided then the owner of the current process is used.
105
+ #
106
+ # The +mask+ is the bitwise OR'd value of access rights.
107
+ #
108
+ # The +flags+ argument can be any one of the following constants:
109
+ #
110
+ # * OBJECT_INHERIT_ACE
111
+ # * CONTAINER_INHERIT_ACE
112
+ # * NO_PROPAGATE_INHERIT_ACE
113
+ # * INHERIT_ONLY_ACE
114
+ # * INHERITED_ACE
115
+ #
116
+ def add_access_denied_ace(sid=nil, mask=0, flags=nil)
117
+ if sid.is_a?(Win32::Security::SID)
118
+ sid = sid.sid
119
+ else
120
+ sid = Win32::Security::SID.new(sid).sid
121
+ end
122
+
123
+ if flags
124
+ unless AddAccessDeniedAceEx(@acl, @revision, flags, mask, sid)
125
+ raise SystemCallError.new("AddAccessDeniedAceEx", FFI.errno)
126
+ end
127
+ else
128
+ unless AddAccessDeniedAce(@acl, @revision, mask, sid)
129
+ raise SystemCallError.new("AddAccessDeniedAce", FFI.errno)
130
+ end
131
+ end
132
+ end
133
+
134
+ # Adds an ACE to the ACL object with the given +revision+ at +index+
135
+ # or the end of the chain if no index is specified.
136
+ #
137
+ # Returns the index if successful.
138
+ #--
139
+ # This won't work until we implement the ACE class.
140
+ #
141
+ def add_ace(ace, index=MAXDWORD)
142
+ unless AddAce(@acl, @revision, index, ace, ace.length)
143
+ raise SystemCallError.new("AddAce", FFI.errno)
144
+ end
145
+
146
+ index
147
+ end
148
+
149
+ # Deletes an ACE from the ACL object at +index+, or from the end of
150
+ # the chain if no index is specified.
151
+ #
152
+ # Returns the index if successful.
153
+ #
154
+ def delete_ace(index=MAXDWORD)
155
+ unless DeleteAce(@acl, index)
156
+ raise SystemCallError.new("DeleteAce", FFI.errno)
157
+ end
158
+
159
+ index
160
+ end
161
+
162
+ # Finds and returns an ACE object for the ACL at the given
163
+ # +index+. If no index is provided, then it returns an ACE object
164
+ # that corresponds to the first free byte of the ACL.
165
+ #
166
+ # If +raw+ is true, it will return an ACCESS_GENERIC_ACE struct,
167
+ # an FFI object that you can then access directly.
168
+ #
169
+ def find_ace(index = nil, raw = false)
170
+ result = nil
171
+
172
+ FFI::MemoryPointer.new(:pointer) do |pptr|
173
+ if index.nil?
174
+ unless FindFirstFreeAce(@acl, pptr)
175
+ raise SystemCallError.new("FindFirstFreeAce", FFI.errno)
176
+ end
177
+ else
178
+ unless GetAce(@acl, index, pptr)
179
+ raise SystemCallError.new("GetAce", FFI.errno)
180
+ end
181
+ end
182
+
183
+ # There's no way to know what type of ACE it is at this point as far
184
+ # as I know, so we use a generic struct and use the AceType to figure
185
+ # it out later, or the users can.
186
+ ace = ACCESS_GENERIC_ACE.new(pptr.read_pointer)
187
+
188
+ if raw
189
+ result = ace
190
+ else
191
+ result = ACE.new(ace[:Mask], ace[:Header][:AceType], ace[:Header][:AceFlags])
192
+ end
193
+ end
194
+
195
+ result
196
+ end
197
+
198
+ # Sets the revision information level, where the +revision_level+
199
+ # can be ACL_REVISION1, ACL_REVISION2, ACL_REVISION3 or ACL_REVISION4.
200
+ #
201
+ # Returns the revision level if successful.
202
+ #
203
+ def revision=(revision_level)
204
+ FFI::MemoryPointer.new(:ulong) do |buf|
205
+ buf.write_ulong(revision_level)
206
+
207
+ unless SetAclInformation(@acl, buf, buf.size, AclRevisionInformation)
208
+ raise SystemCallError.new("SetAclInformation", FFI.errno)
209
+ end
210
+ end
211
+
212
+ @revision = revision_level
213
+
214
+ revision_level
215
+ end
216
+
217
+ # Returns whether or not the ACL is a valid ACL.
218
+ #
219
+ def valid?
220
+ IsValidAcl(@acl)
221
+ end
222
+ end
223
+ end
224
+ end