win32-security 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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