win32-security 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGES CHANGED
@@ -1,2 +1,8 @@
1
+ = 0.1.1 - 14-Jul-2009
2
+ * Added some well known SID's as constants to the Win32::Security::SID class
3
+ for convenience, e.g. SID::World, SID::Everyone.
4
+ * Fixes for the gemspec.
5
+ * Changed license to Artistic 2.0.
6
+
1
7
  = 0.1.0 - 17-Dec-2008
2
- * Initial release
8
+ * Initial release
@@ -25,7 +25,7 @@ module Win32
25
25
  extend Windows::Error
26
26
 
27
27
  # The version of the win32-security library
28
- VERSION = '0.1.0'
28
+ VERSION = '0.1.1'
29
29
 
30
30
  # Returns whether or not the owner of the current process is running
31
31
  # with elevated security privileges.
@@ -0,0 +1,311 @@
1
+ require 'windows/security'
2
+ require 'windows/error'
3
+ require 'windows/msvcrt/string'
4
+ require 'windows/msvcrt/buffer'
5
+ require 'socket'
6
+
7
+ # The Win32 module serves as a namespace only.
8
+ module Win32
9
+
10
+ # The Security class serves as a toplevel class namespace.
11
+ class Security
12
+
13
+ # The SID class encapsulates a Security Identifier.
14
+ class SID
15
+ include Windows::Security
16
+ include Windows::Error
17
+ include Windows::MSVCRT::String
18
+
19
+ extend Windows::Security
20
+ extend Windows::Error
21
+ extend Windows::MSVCRT::String
22
+ extend Windows::MSVCRT::Buffer
23
+
24
+ # Error class typically raised if any of the SID methods fail
25
+ class Error < StandardError; end
26
+
27
+ # The version of the Win32::Security::SID class.
28
+ VERSION = '0.1.1'
29
+
30
+ # Some constant SID's for your convenience, in string format.
31
+ # See http://support.microsoft.com/kb/243330 for details.
32
+
33
+ Null = 'S-1-0'
34
+ Nobody = 'S-1-0-0'
35
+ World = 'S-1-1'
36
+ Everyone = 'S-1-1-0'
37
+ Local = 'S-1-2'
38
+ Creator = 'S-1-3'
39
+ CreatorOwner = 'S-1-3-0'
40
+ CreatorGroup = 'S-1-3-1'
41
+ CreatorOwnerServer = 'S-1-3-2'
42
+ CreatorGroupServer = 'S-1-3-3'
43
+ NonUnique = 'S-1-4'
44
+ Nt = 'S-1-5'
45
+ Dialup = 'S-1-5-1'
46
+ Network = 'S-1-5-2'
47
+ Batch = 'S-1-5-3'
48
+ Interactive = 'S-1-5-4'
49
+ Service = 'S-1-5-6'
50
+ Anonymous = 'S-1-5-7'
51
+ Proxy = 'S-1-5-8'
52
+ EnterpriseDomainControllers = 'S-1-5-9'
53
+ PrincipalSelf = 'S-1-5-10'
54
+ AuthenticatedUsers = 'S-1-5-11'
55
+ RestrictedCode = 'S-1-5-12'
56
+ TerminalServerUsers = 'S-1-5-13'
57
+ LocalSystem = 'S-1-5-18'
58
+ NtLocal = 'S-1-5-19'
59
+ NtNetwork = 'S-1-5-20'
60
+ BuiltinAdministrators = 'S-1-5-32-544'
61
+ BuiltinUsers = 'S-1-5-32-545'
62
+ Guests = 'S-1-5-32-546'
63
+ PowerUsers = 'S-1-5-32-547'
64
+ AccountOperators = 'S-1-5-32-548'
65
+ ServerOperators = 'S-1-5-32-549'
66
+ PrintOperators = 'S-1-5-32-550'
67
+ BackupOperators = 'S-1-5-32-551'
68
+ Replicators = 'S-1-5-32-552'
69
+
70
+ # The binary SID object itself.
71
+ attr_reader :sid
72
+
73
+ # The account name passed to the constructor.
74
+ attr_reader :account
75
+
76
+ # The SID account type, e.g. 'user, 'group', etc.
77
+ attr_reader :account_type
78
+
79
+ # The domain the SID is on.
80
+ attr_reader :domain
81
+
82
+ # The host passed to the constructor, or the localhost if none
83
+ # was specified.
84
+ attr_reader :host
85
+
86
+ # Converts a binary SID to a string in S-R-I-S-S... format.
87
+ #
88
+ def self.sid_to_string(sid)
89
+ sid_addr = [sid].pack('p*').unpack('L')[0]
90
+ sid_buf = 0.chr * 80
91
+ sid_ptr = 0.chr * 4
92
+
93
+ unless ConvertSidToStringSid(sid_addr, sid_ptr)
94
+ raise Error, get_last_error
95
+ end
96
+
97
+ strcpy(sid_buf, sid_ptr.unpack('L')[0])
98
+ sid_buf.strip
99
+ end
100
+
101
+ # Converts a string in S-R-I-S-S... format back to a binary SID.
102
+ #
103
+ def self.string_to_sid(string)
104
+ sid_buf = 0.chr * 80
105
+ string_addr = [string].pack('p*').unpack('L')[0]
106
+
107
+ unless ConvertStringSidToSid(string_addr, sid_buf)
108
+ raise Error, get_last_error
109
+ end
110
+
111
+ sid_buf.strip
112
+ end
113
+
114
+ # Creates a new SID with +authority+ and up to 8 +subauthorities+,
115
+ # and returns new Win32::Security::SID object.
116
+ #
117
+ # Example:
118
+ #
119
+ # sec = Security::SID.create(
120
+ # Security::SID::SECURITY_WORLD_SID_AUTHORITY,
121
+ # Security::SID::SECURITY_WORLD_RID
122
+ # )
123
+ #
124
+ # p sec
125
+ #
126
+ # #<Win32::Security::SID:0x2c5a95c
127
+ # @host="your_host",
128
+ # @account="Everyone",
129
+ # @account_type="well known group",
130
+ # @sid="\001\001\000\000\000\000\000\001\000\000\000\000",
131
+ # @domain=""
132
+ # >
133
+ #
134
+ def self.create(authority, *sub_authorities)
135
+ if sub_authorities.length > 8
136
+ raise ArgumentError, "maximum of 8 subauthorities allowed"
137
+ end
138
+
139
+ sid = 0.chr * GetSidLengthRequired(sub_authorities.length)
140
+
141
+ auth = 0.chr * 5 + authority.chr
142
+
143
+ unless InitializeSid(sid, auth, sub_authorities.length)
144
+ raise Error, get_last_error
145
+ end
146
+
147
+ sub_authorities.each_index do |i|
148
+ value = [sub_authorities[i]].pack('L')
149
+ auth_ptr = GetSidSubAuthority(sid, i)
150
+ memcpy(auth_ptr, value, 4)
151
+ end
152
+
153
+ new(sid)
154
+ end
155
+
156
+ # Creates and returns a new Win32::Security::SID object, based on
157
+ # the account name, which may also be a binary SID. If a host is
158
+ # provided, then the information is retrieved from that host.
159
+ # Otherwise, the local host is used.
160
+ #
161
+ # Note that this does NOT create a new SID, but merely retrieves
162
+ # information for an existing SID. To create a new SID, use the
163
+ # SID.create method.
164
+ #
165
+ # Examples:
166
+ #
167
+ # # User 'john' on the localhost
168
+ # Win32::Security::SID.new('john')
169
+ #
170
+ # # User 'jane' on a remote machine
171
+ # Win32::Security::SID.new('jane', 'some_host')
172
+ #
173
+ # # Binary SID
174
+ # Win32::Security::SID.new("\001\000\000\000\000\000\001\000\000\000\000")
175
+ #
176
+ def initialize(account, host=Socket.gethostname)
177
+ bool = false
178
+ sid = 0.chr * 28
179
+ sid_cb = [sid.size].pack('L')
180
+
181
+ domain_buf = 0.chr * 80
182
+ domain_cch = [domain_buf.size].pack('L')
183
+
184
+ sid_name_use = 0.chr * 4
185
+
186
+ # If characters in the 0-10 range, assume it's a binary SID.
187
+ if account[0] < 10
188
+ bool = LookupAccountSid(
189
+ host,
190
+ [account].pack('p*').unpack('L')[0],
191
+ sid,
192
+ sid_cb,
193
+ domain_buf,
194
+ domain_cch,
195
+ sid_name_use
196
+ )
197
+ else
198
+ bool = LookupAccountName(
199
+ host,
200
+ account,
201
+ sid,
202
+ sid_cb,
203
+ domain_buf,
204
+ domain_cch,
205
+ sid_name_use
206
+ )
207
+ end
208
+
209
+ unless bool
210
+ raise Error, get_last_error
211
+ end
212
+
213
+ # The arguments are flipped if the account argument is binary
214
+ if account[0] < 10
215
+ @sid = account
216
+ @account = sid.strip
217
+ else
218
+ @sid = sid.strip
219
+ @account = account
220
+ end
221
+
222
+ @host = host
223
+ @domain = domain_buf.strip
224
+
225
+ @account_type = get_account_type(sid_name_use.unpack('L')[0])
226
+ end
227
+
228
+ # Synonym for SID.new.
229
+ #
230
+ def self.open(account, host=Socket.gethostname)
231
+ new(account, host)
232
+ end
233
+
234
+ # Returns the binary SID in string format suitable for display,
235
+ # storage or transmission.
236
+ #
237
+ def to_s
238
+ sid_addr = [@sid].pack('p*').unpack('L').first
239
+ sid_buf = 0.chr * 80
240
+ sid_ptr = 0.chr * 4
241
+
242
+ unless ConvertSidToStringSid(sid_addr, sid_ptr)
243
+ raise Error, get_last_error
244
+ end
245
+
246
+ strcpy(sid_buf, sid_ptr.unpack('L').first)
247
+ sid_buf.strip
248
+ end
249
+
250
+ alias to_str to_s
251
+
252
+ # Returns whether or not the SID object is equal to +other+.
253
+ #
254
+ def ==(other)
255
+ EqualSid(@sid, other.sid)
256
+ end
257
+
258
+ # Returns whether or not the SID is a valid sid.
259
+ #
260
+ def valid?
261
+ IsValidSid(@sid)
262
+ end
263
+
264
+ # Returns whether or not the SID is a well known SID.
265
+ #
266
+ # Requires Windows XP or later. Earlier versions will raise a
267
+ # NoMethodError.
268
+ #
269
+ def well_known?
270
+ if defined? IsWellKnownSid
271
+ IsWellKnownSid(@sid)
272
+ else
273
+ raise NoMethodError, 'requires Windows XP or later'
274
+ end
275
+ end
276
+
277
+ # Returns the length of the SID object, in bytes.
278
+ #
279
+ def length
280
+ GetLengthSid(@sid)
281
+ end
282
+
283
+ private
284
+
285
+ # Converts a numeric account type into a human readable string.
286
+ #
287
+ def get_account_type(value)
288
+ case value
289
+ when SidTypeUser
290
+ 'user'
291
+ when SidTypeGroup
292
+ 'group'
293
+ when SidTypeDomain
294
+ 'domain'
295
+ when SidTypeAlias
296
+ 'alias'
297
+ when SidTypeWellKnownGroup
298
+ 'well known group'
299
+ when SidTypeDeletedAccount
300
+ 'deleted account'
301
+ when SidTypeInvalid
302
+ 'invalid'
303
+ when SidTypeUnknown
304
+ 'unknown'
305
+ when SidComputer
306
+ 'computer'
307
+ end
308
+ end
309
+ end
310
+ end
311
+ end
@@ -0,0 +1,67 @@
1
+ ########################################################################
2
+ # test_acl.rb
3
+ #
4
+ # Test suite for the Win32::Security::ACL class. You should run these
5
+ # tests via the 'rake test' task.
6
+ ########################################################################
7
+ require 'rubygems'
8
+ gem 'test-unit'
9
+
10
+ require 'win32/security'
11
+ require 'test/unit'
12
+
13
+ class TC_Win32_Security_Acl < Test::Unit::TestCase
14
+ def setup
15
+ @acl = Security::ACL.new
16
+ end
17
+
18
+ def test_version
19
+ assert_equal('0.1.0', Security::ACL::VERSION)
20
+ end
21
+
22
+ def test_ace_count
23
+ assert_respond_to(@acl, :ace_count)
24
+ assert_kind_of(Fixnum, @acl.ace_count)
25
+ assert_equal(0, @acl.ace_count)
26
+ end
27
+
28
+ def test_acl
29
+ assert_respond_to(@acl, :acl)
30
+ assert_kind_of(String, @acl.acl)
31
+ end
32
+
33
+ def test_add_access_allowed_ace
34
+ assert_respond_to(@acl, :add_access_allowed_ace)
35
+ end
36
+
37
+ def test_add_access_denied_ace
38
+ assert_respond_to(@acl, :add_access_denied_ace)
39
+ end
40
+
41
+ def test_add_ace
42
+ assert_respond_to(@acl, :add_ace)
43
+ end
44
+
45
+ def test_delete_ace
46
+ assert_respond_to(@acl, :delete_ace)
47
+ end
48
+
49
+ def test_find_ace
50
+ assert_respond_to(@acl, :find_ace)
51
+ assert_kind_of(Fixnum, @acl.find_ace)
52
+ end
53
+
54
+ def test_revision
55
+ assert_respond_to(@acl, :revision)
56
+ assert_kind_of(Fixnum, @acl.revision)
57
+ end
58
+
59
+ def test_is_valid
60
+ assert_respond_to(@acl, :valid?)
61
+ assert_equal(true, @acl.valid?)
62
+ end
63
+
64
+ def teardown
65
+ @acl = nil
66
+ end
67
+ end
@@ -12,7 +12,7 @@ require 'win32/security'
12
12
 
13
13
  class TC_Win32_Security < Test::Unit::TestCase
14
14
  def test_version
15
- assert_equal('0.1.0', Win32::Security::VERSION)
15
+ assert_equal('0.1.1', Win32::Security::VERSION)
16
16
  end
17
17
 
18
18
  def test_elevated_security
@@ -23,7 +23,7 @@ class TC_Win32_Security_Sid < Test::Unit::TestCase
23
23
  end
24
24
 
25
25
  def test_version
26
- assert_equal('0.1.0', Security::SID::VERSION)
26
+ assert_equal('0.1.1', Security::SID::VERSION)
27
27
  end
28
28
 
29
29
  def test_sid
@@ -108,6 +108,16 @@ class TC_Win32_Security_Sid < Test::Unit::TestCase
108
108
  assert_raise(Security::SID::Error){ Security::SID.new('bogus') }
109
109
  end
110
110
 
111
+ def test_well_known_sid_constants
112
+ assert_equal('S-1-0', Security::SID::Null)
113
+ assert_equal('S-1-0-0', Security::SID::Nobody)
114
+ assert_equal('S-1-1', Security::SID::World)
115
+ assert_equal('S-1-1-0', Security::SID::Everyone)
116
+ assert_equal('S-1-5-32-544', Security::SID::BuiltinAdministrators)
117
+ assert_equal('S-1-5-32-545', Security::SID::BuiltinUsers)
118
+ assert_equal('S-1-5-32-546', Security::SID::Guests)
119
+ end
120
+
111
121
  def teardown
112
122
  @sid = nil
113
123
  end
@@ -1,32 +1,31 @@
1
- require "rubygems"
1
+ require 'rubygems'
2
2
 
3
3
  spec = Gem::Specification.new do |gem|
4
- gem.name = "win32-security"
5
- gem.version = "0.1.0"
6
- gem.authors = ["Daniel J. Berger", "Park Heesob"]
7
- gem.email = "djberg96@gmail.com"
8
- gem.homepage = "http://www.rubyforge.org/projects/win32utils"
9
- gem.platform = Gem::Platform::RUBY
10
- gem.summary = "A library for dealing with aspects of Windows security."
11
- gem.test_files = Dir["test/*.rb"]
12
- gem.has_rdoc = true
13
- gem.files = Dir["lib/win32/*.rb"] + Dir["test/*"] + Dir["[A-Z]*"]
14
- gem.files.reject! { |fn| fn.include? "CVS" }
15
- gem.extra_rdoc_files = ["README", "CHANGES", "MANIFEST"]
16
- gem.rubyforge_project = 'Win32Utils'
17
-
18
- gem.add_dependency("windows-pr", ">= 0.9.8")
19
- gem.add_dependency("test-unit", ">= 2.0.1")
20
- gem.add_dependency("sys-admin", ">= 1.4.4")
4
+ gem.name = 'win32-security'
5
+ gem.version = '0.1.1'
6
+ gem.authors = ['Daniel J. Berger', 'Park Heesob']
7
+ gem.email = 'djberg96@gmail.com'
8
+ gem.homepage = 'http://www.rubyforge.org/projects/win32utils'
9
+ gem.platform = Gem::Platform::RUBY
10
+ gem.summary = 'A library for dealing with aspects of Windows security.'
11
+ gem.test_files = Dir['test/*.rb']
12
+ gem.has_rdoc = true
13
+ gem.files = Dir['**/*'].reject{ |f| f.include?('CVS') }
14
+ gem.license = 'Artistic 2.0'
15
+
16
+ gem.extra_rdoc_files = ['README', 'CHANGES', 'MANIFEST']
17
+ gem.rubyforge_project = 'win32utils'
21
18
 
22
- description = "The win32-security library provides an interface for dealing"
23
- description << " with security aspects of MS Windows. It includes classes"
24
- description << " for SID's, ACL's and ACE's."
19
+ gem.add_dependency('windows-pr', '>= 0.9.8')
20
+ gem.add_dependency('test-unit', '>= 2.0.1')
21
+ gem.add_dependency('sys-admin', '>= 1.4.4')
25
22
 
26
- gem.description = description
23
+ gem.description = <<-EOF
24
+ The win32-security library provides an interface for dealing with
25
+ security related aspects of MS Windows. At the moment it provides an
26
+ interface for inspecting or creating SID's.
27
+ EOF
27
28
  end
28
29
 
29
- if $0 == __FILE__
30
- Gem.manage_gems if Gem::RubyGemsVersion.to_f < 1.0
31
- Gem::Builder.new(spec).build
32
- end
30
+ Gem.manage_gems if Gem::RubyGemsVersion.to_f < 1.0
31
+ Gem::Builder.new(spec).build
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: win32-security
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2008-12-17 00:00:00 -07:00
13
+ date: 2009-07-14 00:00:00 -06:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -43,7 +43,7 @@ dependencies:
43
43
  - !ruby/object:Gem::Version
44
44
  version: 1.4.4
45
45
  version:
46
- description: The win32-security library provides an interface for dealing with security aspects of MS Windows. It includes classes for SID's, ACL's and ACE's.
46
+ description: " The win32-security library provides an interface for dealing with\n security related aspects of MS Windows. At the moment it provides an\n interface for inspecting or creating SID's.\n"
47
47
  email: djberg96@gmail.com
48
48
  executables: []
49
49
 
@@ -54,18 +54,20 @@ extra_rdoc_files:
54
54
  - CHANGES
55
55
  - MANIFEST
56
56
  files:
57
- - lib/win32/security.rb
58
- - test/test_security.rb
59
- - test/test_sid.rb
60
57
  - CHANGES
61
- - lib
58
+ - lib/win32/security/sid.rb
59
+ - lib/win32/security.rb
62
60
  - MANIFEST
63
61
  - Rakefile
64
62
  - README
65
- - test
63
+ - test/test_acl.rb
64
+ - test/test_security.rb
65
+ - test/test_sid.rb
66
66
  - win32-security.gemspec
67
67
  has_rdoc: true
68
68
  homepage: http://www.rubyforge.org/projects/win32utils
69
+ licenses:
70
+ - Artistic 2.0
69
71
  post_install_message:
70
72
  rdoc_options: []
71
73
 
@@ -85,11 +87,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
87
  version:
86
88
  requirements: []
87
89
 
88
- rubyforge_project: Win32Utils
89
- rubygems_version: 1.3.1
90
+ rubyforge_project: win32utils
91
+ rubygems_version: 1.3.4
90
92
  signing_key:
91
- specification_version: 2
93
+ specification_version: 3
92
94
  summary: A library for dealing with aspects of Windows security.
93
95
  test_files:
96
+ - test/test_acl.rb
94
97
  - test/test_security.rb
95
98
  - test/test_sid.rb