win32-security 0.1.2 → 0.1.3

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,3 +1,9 @@
1
+ = 0.1.3 - 12-Jul-2012
2
+ * The SID.new method now defaults to the owner of the current thread if
3
+ no account name is provided.
4
+ * Updates to the gemspec, Rakefile, and SID tests, including updates to
5
+ some of the gemspec dependencies.
6
+
1
7
  = 0.1.2 - 2-Aug-2009
2
8
  * Now compatible with Ruby 1.9.x.
3
9
  * Switched test-unit and sys-admin from standard dependencies to development
data/README CHANGED
@@ -1,35 +1,35 @@
1
1
  = Description
2
- A security library for MS Windows that allows you to open existing or
3
- create new security identifiers (SID's).
2
+ A security library for MS Windows that allows you to open existing or
3
+ create new security identifiers (SID's).
4
4
 
5
5
  = Synopsis
6
- require 'win32/security'
7
- include Win32
6
+ require 'win32/security'
7
+ include Win32
8
8
 
9
- sid = Security::SID.open('djberge')
9
+ sid = Security::SID.open('some_user')
10
10
 
11
- sid.valid? # => true
12
- sid.to_s # => "S-1-5-21-3733855671-1102023144-2002619019-1000"
13
- sid.length # => 28
14
- sid.sid # => "\001\005\000\000\000\000\000\005\025\000\000\000..."
11
+ sid.valid? # => true
12
+ sid.to_s # => "S-1-5-21-3733855671-1102023144-2002619019-1000"
13
+ sid.length # => 28
14
+ sid.sid # => "\001\005\000\000\000\000\000\005\025\000\000\000..."
15
15
 
16
16
  == Future Plans
17
- Create classes that encapsulate ACL's, ACE's, Token's, etc.
17
+ Create classes that encapsulate ACL's, ACE's, Token's, etc.
18
18
 
19
- There are some unfinished versions of the ACL and ACE classes in CVS
20
- if you're interested in taking a look.
19
+ There are some unfinished versions of the ACL and ACE classes in the
20
+ repo if you're interested in taking a look.
21
21
 
22
22
  == Known Issues
23
- None that I'm aware of. Please file any bug reports on the project page
24
- at http://www.rubyforge.org/projects/win32utils.
23
+ None that I'm aware of. Please file any bug reports on the project page
24
+ at http://www.rubyforge.org/projects/win32utils.
25
25
 
26
26
  == License
27
- Ruby's
27
+ Artistic 2.0
28
28
 
29
29
  == Copyright
30
- (C) 2003-2009 Daniel J. Berger
31
- All Rights Reserved
30
+ (C) 2003-2012 Daniel J. Berger
31
+ All Rights Reserved
32
32
 
33
33
  == Authors
34
- Daniel J. Berger
35
- Park Heesob
34
+ Daniel J. Berger
35
+ Park Heesob
data/Rakefile CHANGED
@@ -1,37 +1,46 @@
1
1
  require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'rbconfig'
4
- include Config
5
4
 
6
- desc 'Cleanup any temp files left over by Test::Unit'
7
- task :clean do
8
- Dir['*'].each{ |file|
9
- file = File.expand_path(file)
10
- next unless File.directory?(file)
11
- next if file =~ /CVS/
12
- Dir.chdir(file) do
13
- rm_rf '.test-result' if File.exists?('.test-result')
14
- end
15
- }
5
+ namespace :gem do
6
+ desc "Remove any .gem files in the project"
7
+ task :clean do
8
+ Dir['*.gem'].each{ |f| File.delete(f) }
9
+ end
16
10
 
17
- desc 'Install the win32-security package (non-gem)'
18
- task :install do
19
- install_dir = File.join(CONFIG["sitelibdir"], 'win32', 'security')
20
- mkdir_p(install_dir) unless File.exists?(install_dir)
21
- cp 'lib/win32/security.rb', File.dirname(install_dir), :verbose => true
22
- cp 'lib/win32/security/acl.rb', install_dir, :verbose => true
23
- cp 'lib/win32/security/sid.rb', install_dir, :verbose => true
24
- end
11
+ desc "Create the win32-security gem"
12
+ task :create => [:clean] do
13
+ spec = eval(IO.read('win32-security.gemspec'))
14
+ Gem::Builder.new(spec).build
15
+ end
25
16
 
26
- task :install_gem do
27
- ruby 'win32-security.gemspec'
28
- file = Dir["*.gem"].first
29
- sh "gem install #{file}"
17
+ desc "Install the win32-security gem"
18
+ task :install => [:create] do
19
+ ruby 'win32-security.gemspec'
20
+ file = Dir["*.gem"].first
21
+ sh "gem install #{file}"
22
+ end
30
23
  end
31
24
 
32
- # TODO: Add more test files as more classes are added.
33
- Rake::TestTask.new do |t|
34
- t.verbose = true
35
- t.warning = true
36
- t.test_files = Dir['test/test_sid.rb', 'test/test_security.rb']
25
+ namespace :test do
26
+ Rake::TestTask.new(:security) do |t|
27
+ t.verbose = true
28
+ t.warning = true
29
+ t.test_files = Dir['test/test_security.rb']
30
+ end
31
+
32
+ Rake::TestTask.new(:sid) do |t|
33
+ t.verbose = true
34
+ t.warning = true
35
+ t.test_files = Dir['test/test_sid.rb']
36
+ end
37
+
38
+ # ACL class isn't ready yet
39
+ Rake::TestTask.new(:all) do |t|
40
+ t.verbose = true
41
+ t.warning = true
42
+ t.test_files = Dir['test/test_sid.rb', 'test/test_security.rb']
43
+ end
37
44
  end
45
+
46
+ task :default => 'test:all'
@@ -6,59 +6,60 @@ require 'windows/security'
6
6
  require 'windows/handle'
7
7
  require 'windows/error'
8
8
 
9
- $LOAD_PATH.unshift(File.dirname(File.dirname(File.expand_path(__FILE__))))
10
-
11
9
  # The Win32 module serves as a namespace only.
12
10
  module Win32
13
11
 
14
- # The Security class encapsulates security aspects of MS Windows.
15
- class Security
12
+ # The Security class encapsulates security aspects of MS Windows.
13
+ class Security
16
14
 
17
- # Base error class for all Win32::Security errors.
18
- class Error < StandardError; end
15
+ # Base error class for all Win32::Security errors.
16
+ class Error < StandardError; end
19
17
 
20
- include Windows::Security
18
+ include Windows::Security
21
19
 
22
- extend Windows::Process
23
- extend Windows::Security
24
- extend Windows::Handle
25
- extend Windows::Error
20
+ extend Windows::Process
21
+ extend Windows::Security
22
+ extend Windows::Handle
23
+ extend Windows::Error
26
24
 
27
- # The version of the win32-security library
28
- VERSION = '0.1.2'
25
+ # The version of the win32-security library
26
+ VERSION = '0.1.3'
29
27
 
30
- # Returns whether or not the owner of the current process is running
31
- # with elevated security privileges.
32
- #
33
- def self.elevated_security?
34
- token = 0.chr * 4
28
+ # Returns whether or not the owner of the current process is running
29
+ # with elevated security privileges.
30
+ #
31
+ # Only supported on Windows Vista or later.
32
+ #
33
+ def self.elevated_security?
34
+ token = 0.chr * 4
35
35
 
36
- unless OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, token)
37
- raise Error, get_last_error
38
- end
36
+ unless OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, token)
37
+ raise Error, get_last_error
38
+ end
39
39
 
40
- begin
41
- token = token.unpack('V')[0]
40
+ begin
41
+ token = token.unpack('V')[0]
42
42
 
43
- te = 0.chr * 4 # TOKEN_ELEVATION
44
- rl = 0.chr * 4 # Return length
43
+ te = 0.chr * 4 # TOKEN_ELEVATION
44
+ rl = 0.chr * 4 # Return length
45
45
 
46
- bool = GetTokenInformation(
47
- token,
48
- TokenElevation,
49
- te,
50
- te.size,
51
- rl
52
- )
46
+ bool = GetTokenInformation(
47
+ token,
48
+ TokenElevation,
49
+ te,
50
+ te.size,
51
+ rl
52
+ )
53
53
 
54
- raise Error, get_last_error unless bool
55
- ensure
56
- CloseHandle(token)
57
- end
58
-
59
- te.unpack('L')[0] != 0
54
+ raise Error, get_last_error unless bool
55
+ ensure
56
+ CloseHandle(token)
60
57
  end
61
- end
58
+
59
+ # TokenIsElevated member of the TOKEN_ELEVATION struct
60
+ te.unpack('L')[0] != 0
61
+ end
62
+ end
62
63
  end
63
64
 
64
65
  require 'win32/security/sid'
@@ -1,39 +1,39 @@
1
1
  # The Win32 module serves as a namespace only.
2
2
  module Win32
3
3
 
4
- # The Security class serves as a toplevel class namespace.
5
- class Security
4
+ # The Security class serves as a toplevel class namespace.
5
+ class Security
6
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'
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
12
 
13
- # The ACE type, e.g. ACCESS_ALLOWED, ACCESS_DENIED, etc.
14
- attr_accessor :ace_type
13
+ # The ACE type, e.g. ACCESS_ALLOWED, ACCESS_DENIED, etc.
14
+ attr_accessor :ace_type
15
15
 
16
- # The ACE mask, e.g. INHERITED_ACE
17
- attr_accessor :ace_mask
16
+ # The ACE mask, e.g. INHERITED_ACE
17
+ attr_accessor :ace_mask
18
18
 
19
- # Standard access rights, e.g. GENERIC_READ, GENERIC_WRITE, etc
20
- attr_accessor :access_mask
19
+ # Standard access rights, e.g. GENERIC_READ, GENERIC_WRITE, etc
20
+ attr_accessor :access_mask
21
21
 
22
- # Bit flags that indicate whether the ObjectType and
23
- # InheritedObjectType members are present. This value is set
24
- # internally based on the values passed to the ACE#object_type or
25
- # ACE#inherited_object_type methods, if any.
26
- attr_reader :flags
22
+ # Bit flags that indicate whether the ObjectType and
23
+ # InheritedObjectType members are present. This value is set
24
+ # internally based on the values passed to the ACE#object_type or
25
+ # ACE#inherited_object_type methods, if any.
26
+ attr_reader :flags
27
27
 
28
- # A Win32::Security::GUID object that identifies the type of child
29
- # object that can inherit the ACE.
30
- attr_accessor :object_type
28
+ # A Win32::Security::GUID object that identifies the type of child
29
+ # object that can inherit the ACE.
30
+ attr_accessor :object_type
31
31
 
32
- attr_accessor :inherited_object_type
32
+ attr_accessor :inherited_object_type
33
33
 
34
- def initialize
35
- yield self if block_given?
36
- end
34
+ def initialize
35
+ yield self if block_given?
37
36
  end
38
- end
37
+ end
38
+ end
39
39
  end
@@ -6,143 +6,143 @@ require 'windows/msvcrt/buffer'
6
6
  # The Win32 module serves as a namespace only.
7
7
  module Win32
8
8
 
9
- # The Security class serves as a toplevel class namespace.
10
- class Security
9
+ # The Security class serves as a toplevel class namespace.
10
+ class Security
11
11
 
12
- # The ACL class encapsulates an Access Control List.
13
- class ACL
14
- include Windows::Error
15
- include Windows::Security
16
- include Windows::Limits
17
- include Windows::MSVCRT::Buffer
12
+ # The ACL class encapsulates an Access Control List.
13
+ class ACL
14
+ include Windows::Error
15
+ include Windows::Security
16
+ include Windows::Limits
17
+ include Windows::MSVCRT::Buffer
18
18
 
19
- # The version of the Win32::Security::ACL class.
20
- VERSION = '0.1.0'
21
-
22
- # The binary representation of the ACL structure
23
- attr_reader :acl
24
-
25
- # The revision level.
26
- attr_reader :revision
27
-
28
- # Creates and returns a new Win32::Security::ACL object. This object
29
- # encapsulates an ACL structure, including a binary representation of
30
- # the ACL itself, and the revision information.
31
- #
32
- def initialize(revision = ACL_REVISION)
33
- acl = 0.chr * 8 # This can be increased later as needed
34
-
35
- unless InitializeAcl(acl, acl.size, revision)
36
- raise Error, get_last_error
37
- end
38
-
39
- @acl = acl
40
- @revision = revision
41
- end
42
-
43
- # Returns the number of ACE's in the ACL object.
44
- #
45
- def ace_count
46
- buf = 0.chr * 12 # sizeof(ACL_SIZE_INFORMATION)
47
-
48
- unless GetAclInformation(@acl, buf, buf.size, AclSizeInformation)
49
- raise Error, get_last_error
50
- end
51
-
52
- buf[0, 4].unpack('L')[0]
53
- end
54
-
55
- # Adds an access allowed ACE to the given +sid+. The +mask+ is a
56
- # bitwise OR'd value of access rights.
57
- #
58
- def add_access_allowed_ace(sid, mask=0)
59
- unless AddAccessAllowedAce(@acl, @revision, mask, sid)
60
- raise Error, get_last_error
61
- end
62
- end
63
-
64
- # Adds an access denied ACE to the given +sid+.
65
- #
66
- def add_access_denied_ace(sid, mask=0)
67
- unless AddAccessDeniedAce(@acl, @revision, mask, sid)
68
- raise Error, get_last_error
69
- end
70
- end
71
-
72
- # Adds an ACE to the ACL object with the given +revision+ at +index+
73
- # or the end of the chain if no index is specified.
74
- #
75
- # Returns the index if successful.
76
- #--
77
- # This is untested and will require an actual implementation of
78
- # Win32::Security::Ace before it can work properly.
79
- #
80
- def add_ace(ace, index=MAXDWORD)
81
- unless AddAce(@acl, @revision, index, ace, ace.length)
82
- raise Error, get_last_error
83
- end
84
-
85
- index
86
- end
87
-
88
- # Deletes an ACE from the ACL object at +index+, or from the end of
89
- # the chain if no index is specified.
90
- #
91
- # Returns the index if successful.
92
- #--
93
- # This is untested and will require an actual implementation of
94
- # Win32::Security::Ace before it can work properly.
95
- #
96
- def delete_ace(index=MAXDWORD)
97
- unless DeleteAce(@ace, index)
98
- raise Error, get_last_error
99
- end
100
-
101
- index
102
- end
103
-
104
- # Finds and returns a pointer (address) to an ACE in the ACL at the
105
- # given +index+. If no index is provided, then an address to the
106
- # first free byte of the ACL is returned.
107
- #
108
- def find_ace(index = nil)
109
- ptr = [0].pack('L')
110
-
111
- if index.nil?
112
- unless FindFirstFreeAce(@acl, ptr)
113
- raise Error, get_last_error
114
- end
115
- else
116
- unless GetAce(@acl, index, ptr)
117
- raise Error, get_last_error
118
- end
119
- end
120
-
121
- [ptr].pack('p*').unpack('L')[0]
122
- end
123
-
124
- # Sets the revision information level, where the +revision_level+
125
- # can be ACL_REVISION1, ACL_REVISION2, ACL_REVISION3 or ACL_REVISION4.
126
- #
127
- # Returns the revision level if successful.
128
- #
129
- def revision=(revision_level)
130
- buf = [revision_level].pack('L')
131
-
132
- unless SetAclInformation(@acl, buf, buf.size, AclRevisionInformation)
133
- raise Error, get_last_error
134
- end
135
-
136
- @revision = revision_level
137
-
138
- revision_level
139
- end
140
-
141
- # Returns whether or not the ACL is a valid ACL.
142
- #
143
- def valid?
144
- IsValidAcl(@acl)
145
- end
19
+ # The version of the Win32::Security::ACL class.
20
+ VERSION = '0.1.0'
21
+
22
+ # The binary representation of the ACL structure
23
+ attr_reader :acl
24
+
25
+ # The revision level.
26
+ attr_reader :revision
27
+
28
+ # Creates and returns a new Win32::Security::ACL object. This object
29
+ # encapsulates an ACL structure, including a binary representation of
30
+ # the ACL itself, and the revision information.
31
+ #
32
+ def initialize(revision = ACL_REVISION)
33
+ acl = 0.chr * 8 # This can be increased later as needed
34
+
35
+ unless InitializeAcl(acl, acl.size, revision)
36
+ raise Error, get_last_error
37
+ end
38
+
39
+ @acl = acl
40
+ @revision = revision
41
+ end
42
+
43
+ # Returns the number of ACE's in the ACL object.
44
+ #
45
+ def ace_count
46
+ buf = 0.chr * 12 # sizeof(ACL_SIZE_INFORMATION)
47
+
48
+ unless GetAclInformation(@acl, buf, buf.size, AclSizeInformation)
49
+ raise Error, get_last_error
50
+ end
51
+
52
+ buf[0, 4].unpack('L')[0]
53
+ end
54
+
55
+ # Adds an access allowed ACE to the given +sid+. The +mask+ is a
56
+ # bitwise OR'd value of access rights.
57
+ #
58
+ def add_access_allowed_ace(sid, mask=0)
59
+ unless AddAccessAllowedAce(@acl, @revision, mask, sid)
60
+ raise Error, get_last_error
61
+ end
62
+ end
63
+
64
+ # Adds an access denied ACE to the given +sid+.
65
+ #
66
+ def add_access_denied_ace(sid, mask=0)
67
+ unless AddAccessDeniedAce(@acl, @revision, mask, sid)
68
+ raise Error, get_last_error
69
+ end
70
+ end
71
+
72
+ # Adds an ACE to the ACL object with the given +revision+ at +index+
73
+ # or the end of the chain if no index is specified.
74
+ #
75
+ # Returns the index if successful.
76
+ #--
77
+ # This is untested and will require an actual implementation of
78
+ # Win32::Security::Ace before it can work properly.
79
+ #
80
+ def add_ace(ace, index=MAXDWORD)
81
+ unless AddAce(@acl, @revision, index, ace, ace.length)
82
+ raise Error, get_last_error
83
+ end
84
+
85
+ index
86
+ end
87
+
88
+ # Deletes an ACE from the ACL object at +index+, or from the end of
89
+ # the chain if no index is specified.
90
+ #
91
+ # Returns the index if successful.
92
+ #--
93
+ # This is untested and will require an actual implementation of
94
+ # Win32::Security::Ace before it can work properly.
95
+ #
96
+ def delete_ace(index=MAXDWORD)
97
+ unless DeleteAce(@ace, index)
98
+ raise Error, get_last_error
99
+ end
100
+
101
+ index
102
+ end
103
+
104
+ # Finds and returns a pointer (address) to an ACE in the ACL at the
105
+ # given +index+. If no index is provided, then an address to the
106
+ # first free byte of the ACL is returned.
107
+ #
108
+ def find_ace(index = nil)
109
+ ptr = [0].pack('L')
110
+
111
+ if index.nil?
112
+ unless FindFirstFreeAce(@acl, ptr)
113
+ raise Error, get_last_error
114
+ end
115
+ else
116
+ unless GetAce(@acl, index, ptr)
117
+ raise Error, get_last_error
118
+ end
119
+ end
120
+
121
+ [ptr].pack('p*').unpack('L')[0]
122
+ end
123
+
124
+ # Sets the revision information level, where the +revision_level+
125
+ # can be ACL_REVISION1, ACL_REVISION2, ACL_REVISION3 or ACL_REVISION4.
126
+ #
127
+ # Returns the revision level if successful.
128
+ #
129
+ def revision=(revision_level)
130
+ buf = [revision_level].pack('L')
131
+
132
+ unless SetAclInformation(@acl, buf, buf.size, AclRevisionInformation)
133
+ raise Error, get_last_error
134
+ end
135
+
136
+ @revision = revision_level
137
+
138
+ revision_level
139
+ end
140
+
141
+ # Returns whether or not the ACL is a valid ACL.
142
+ #
143
+ def valid?
144
+ IsValidAcl(@acl)
146
145
  end
147
- end
146
+ end
147
+ end
148
148
  end