chef 11.14.0.rc.2-x86-mingw32 → 11.14.2-x86-mingw32
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.
- checksums.yaml +7 -0
- data/lib/chef/formatters/base.rb +7 -0
- data/lib/chef/http/basic_client.rb +7 -1
- data/lib/chef/knife/cookbook_site_share.rb +4 -1
- data/lib/chef/mixin/file_class.rb +4 -1
- data/lib/chef/mixin/params_validate.rb +7 -0
- data/lib/chef/provider/log.rb +1 -15
- data/lib/chef/provider/package/dpkg.rb +1 -0
- data/lib/chef/provider/service/windows.rb +14 -11
- data/lib/chef/resource/lwrp_base.rb +58 -14
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/api/net.rb +90 -0
- data/lib/chef/win32/security/sid.rb +53 -3
- data/lib/chef/win32/unicode.rb +13 -1
- data/spec/functional/file_content_management/deploy_strategies_spec.rb +9 -8
- data/spec/integration/knife/common_options_spec.rb +2 -1
- data/spec/stress/win32/file_spec.rb +1 -7
- data/spec/support/matchers/leak.rb +1 -1
- data/spec/support/shared/functional/securable_resource.rb +14 -7
- data/spec/unit/formatters/base_spec.rb +48 -0
- data/spec/unit/http/basic_client_spec.rb +35 -1
- data/spec/unit/knife/cookbook_site_share_spec.rb +5 -5
- data/spec/unit/lwrp_spec.rb +120 -0
- data/spec/unit/provider/log_spec.rb +0 -18
- metadata +151 -220
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6a769335871e4cce7e78eff16d59ba21dd9c21ef
|
4
|
+
data.tar.gz: 94a150ebe02c901760bbab6a0f31d8011f5212d8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f9697925a23425abf449eb9c81c2815ad944dfc4026f50268949fbf36af364cc91e878b1a81ab87b2dfc435174ca94ad161a13719f417a54453fa65f53430e6d
|
7
|
+
data.tar.gz: 9c530b98bf372daa14a7fd39f614d2a5f49e0cf4a749a0b48dab3f2adc1dcea0d449326d1185fa7d34a50aee86240fea88c1b7236113837f9eb91642f408c727
|
data/lib/chef/formatters/base.rb
CHANGED
@@ -93,6 +93,13 @@ class Chef
|
|
93
93
|
|
94
94
|
def indent_by(amount)
|
95
95
|
@output.indent += amount
|
96
|
+
if @output.indent < 0
|
97
|
+
# This is left commented out for now. We need to uncomment it and fix at least one bug in
|
98
|
+
# the formatter, and then leave this line uncommented in the future.
|
99
|
+
#Chef::Log.warn "Internal Formatter Error -- Attempt to indent by negative number of spaces"
|
100
|
+
@output.indent = 0
|
101
|
+
end
|
102
|
+
@output.indent
|
96
103
|
end
|
97
104
|
|
98
105
|
# Input: a Formatters::ErrorDescription object.
|
@@ -84,7 +84,13 @@ class Chef
|
|
84
84
|
#adapted from buildr/lib/buildr/core/transports.rb
|
85
85
|
def proxy_uri
|
86
86
|
proxy = Chef::Config["#{url.scheme}_proxy"]
|
87
|
-
proxy
|
87
|
+
# Check if the proxy string contains a scheme. If not, add the url's scheme to the
|
88
|
+
# proxy before parsing. The regex /^.*:\/\// matches, for example, http://.
|
89
|
+
proxy = if proxy.match(/^.*:\/\//)
|
90
|
+
URI.parse(proxy)
|
91
|
+
else
|
92
|
+
URI.parse("#{url.scheme}://#{proxy}")
|
93
|
+
end if String === proxy
|
88
94
|
excludes = Chef::Config[:no_proxy].to_s.split(/\s*,\s*/).compact
|
89
95
|
excludes = excludes.map { |exclude| exclude =~ /:\d+$/ ? exclude : "#{exclude}:*" }
|
90
96
|
return proxy unless excludes.any? { |exclude| File.fnmatch(exclude, "#{host}:#{port}") }
|
@@ -17,11 +17,14 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'chef/knife'
|
20
|
+
require 'chef/mixin/shell_out'
|
20
21
|
|
21
22
|
class Chef
|
22
23
|
class Knife
|
23
24
|
class CookbookSiteShare < Knife
|
24
25
|
|
26
|
+
include Chef::Mixin::ShellOut
|
27
|
+
|
25
28
|
deps do
|
26
29
|
require 'chef/cookbook_loader'
|
27
30
|
require 'chef/cookbook_uploader'
|
@@ -56,7 +59,7 @@ class Chef
|
|
56
59
|
begin
|
57
60
|
Chef::Log.debug("Temp cookbook directory is #{tmp_cookbook_dir.inspect}")
|
58
61
|
ui.info("Making tarball #{cookbook_name}.tgz")
|
59
|
-
|
62
|
+
shell_out!("tar -czf #{cookbook_name}.tgz #{cookbook_name}", :cwd => tmp_cookbook_dir)
|
60
63
|
rescue => e
|
61
64
|
ui.error("Error making tarball #{cookbook_name}.tgz: #{e.message}. Increase log verbosity (-VV) for more information.")
|
62
65
|
Chef::Log.debug("\n#{e.backtrace.join("\n")}")
|
@@ -18,13 +18,16 @@
|
|
18
18
|
# limitations under the License.
|
19
19
|
#
|
20
20
|
|
21
|
+
if Chef::Platform.windows?
|
22
|
+
require 'chef/win32/file'
|
23
|
+
end
|
24
|
+
|
21
25
|
class Chef
|
22
26
|
module Mixin
|
23
27
|
module FileClass
|
24
28
|
|
25
29
|
def file_class
|
26
30
|
@host_os_file ||= if Chef::Platform.windows?
|
27
|
-
require 'chef/win32/file'
|
28
31
|
Chef::ReservedNames::Win32::File
|
29
32
|
else
|
30
33
|
::File
|
@@ -95,6 +95,13 @@ class Chef
|
|
95
95
|
val = arg
|
96
96
|
else
|
97
97
|
val = validate({ symbol => arg }, { symbol => validation })[symbol]
|
98
|
+
|
99
|
+
# Handle the case where the "default" was a DelayedEvaluator. In
|
100
|
+
# this case, the block yields an optional parameter of +self+,
|
101
|
+
# which is the equivalent of "new_resource"
|
102
|
+
if val.is_a?(DelayedEvaluator)
|
103
|
+
val = val.call(self)
|
104
|
+
end
|
98
105
|
end
|
99
106
|
self.instance_variable_set(iv_symbol, val)
|
100
107
|
end
|
data/lib/chef/provider/log.rb
CHANGED
@@ -25,9 +25,6 @@ class Chef
|
|
25
25
|
# Chef log provider, allows logging to chef's logs from recipes
|
26
26
|
class ChefLog < Chef::Provider
|
27
27
|
|
28
|
-
# ordered array of the log levels
|
29
|
-
@@levels = [ :debug, :info, :warn, :error, :fatal ]
|
30
|
-
|
31
28
|
# No concept of a 'current' resource for logs, this is a no-op
|
32
29
|
#
|
33
30
|
# === Return
|
@@ -42,18 +39,7 @@ class Chef
|
|
42
39
|
# true:: Always return true
|
43
40
|
def action_write
|
44
41
|
Chef::Log.send(@new_resource.level, @new_resource.message)
|
45
|
-
|
46
|
-
# resolve the integers for the current log levels
|
47
|
-
global_level = Mixlib::Log::LEVELS.fetch(Chef::Log.level)
|
48
|
-
resource_level = Mixlib::Log::LEVELS.fetch(@new_resource.level)
|
49
|
-
|
50
|
-
# If the resource level is greater than or the same os the global
|
51
|
-
# level, then it should have been written to the log. Mark the
|
52
|
-
# resource as updated.
|
53
|
-
if resource_level >= global_level
|
54
|
-
@new_resource.updated_by_last_action(true)
|
55
|
-
end
|
56
|
-
|
42
|
+
@new_resource.updated_by_last_action(true)
|
57
43
|
end
|
58
44
|
|
59
45
|
end
|
@@ -64,9 +64,7 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
|
|
64
64
|
Chef::Log.debug "#{@new_resource} already started - nothing to do"
|
65
65
|
elsif state == START_PENDING
|
66
66
|
Chef::Log.debug "#{@new_resource} already sent start signal - waiting for start"
|
67
|
-
|
68
|
-
wait_for_state(RUNNING)
|
69
|
-
end
|
67
|
+
wait_for_state(RUNNING)
|
70
68
|
elsif state == STOPPED
|
71
69
|
if @new_resource.start_command
|
72
70
|
Chef::Log.debug "#{@new_resource} starting service using the given start_command"
|
@@ -74,8 +72,8 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
|
|
74
72
|
else
|
75
73
|
spawn_command_thread do
|
76
74
|
Win32::Service.start(@new_resource.service_name)
|
77
|
-
wait_for_state(RUNNING)
|
78
75
|
end
|
76
|
+
wait_for_state(RUNNING)
|
79
77
|
end
|
80
78
|
@new_resource.updated_by_last_action(true)
|
81
79
|
else
|
@@ -96,17 +94,15 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
|
|
96
94
|
else
|
97
95
|
spawn_command_thread do
|
98
96
|
Win32::Service.stop(@new_resource.service_name)
|
99
|
-
wait_for_state(STOPPED)
|
100
97
|
end
|
98
|
+
wait_for_state(STOPPED)
|
101
99
|
end
|
102
100
|
@new_resource.updated_by_last_action(true)
|
103
101
|
elsif state == STOPPED
|
104
102
|
Chef::Log.debug "#{@new_resource} already stopped - nothing to do"
|
105
103
|
elsif state == STOP_PENDING
|
106
104
|
Chef::Log.debug "#{@new_resource} already sent stop signal - waiting for stop"
|
107
|
-
|
108
|
-
wait_for_state(STOPPED)
|
109
|
-
end
|
105
|
+
wait_for_state(STOPPED)
|
110
106
|
else
|
111
107
|
raise Chef::Exceptions::Service, "Service #{@new_resource} can't be stopped from state [#{state}]"
|
112
108
|
end
|
@@ -174,7 +170,16 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
|
|
174
170
|
# Helper method that waits for a status to change its state since state
|
175
171
|
# changes aren't usually instantaneous.
|
176
172
|
def wait_for_state(desired_state)
|
177
|
-
|
173
|
+
retries = 0
|
174
|
+
loop do
|
175
|
+
break if current_state == desired_state
|
176
|
+
raise Timeout::Error if ( retries += 1 ) > resource_timeout
|
177
|
+
sleep 1
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def resource_timeout
|
182
|
+
@resource_timeout ||= @new_resource.timeout || TIMEOUT
|
178
183
|
end
|
179
184
|
|
180
185
|
def spawn_command_thread
|
@@ -182,8 +187,6 @@ class Chef::Provider::Service::Windows < Chef::Provider::Service
|
|
182
187
|
yield
|
183
188
|
end
|
184
189
|
|
185
|
-
resource_timeout = @new_resource.timeout if @new_resource.timeout
|
186
|
-
resource_timeout ||= TIMEOUT
|
187
190
|
Timeout.timeout(resource_timeout) do
|
188
191
|
worker.join
|
189
192
|
end
|
@@ -59,15 +59,17 @@ class Chef
|
|
59
59
|
resource_class
|
60
60
|
end
|
61
61
|
|
62
|
-
# Set the resource
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
# Set the resource name for this LWRP
|
63
|
+
def self.resource_name(arg = NULL_ARG)
|
64
|
+
if arg.equal?(NULL_ARG)
|
65
|
+
@resource_name
|
66
|
+
else
|
67
|
+
@resource_name = arg
|
68
|
+
end
|
66
69
|
end
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
@resource_name
|
71
|
+
class << self
|
72
|
+
alias_method :resource_name=, :resource_name
|
71
73
|
end
|
72
74
|
|
73
75
|
# Define an attribute on this resource, including optional validation
|
@@ -90,19 +92,39 @@ class Chef
|
|
90
92
|
# Sets the default action
|
91
93
|
def self.default_action(action_name=NULL_ARG)
|
92
94
|
unless action_name.equal?(NULL_ARG)
|
93
|
-
|
94
|
-
|
95
|
+
@actions ||= []
|
96
|
+
if action_name.is_a?(Array)
|
97
|
+
action = action_name.map { |arg| arg.to_sym }
|
98
|
+
@actions = actions | action
|
99
|
+
@default_action = action
|
100
|
+
else
|
101
|
+
action = action_name.to_sym
|
102
|
+
@actions.push(action) unless @actions.include?(action)
|
103
|
+
@default_action = action
|
104
|
+
end
|
95
105
|
end
|
96
|
-
|
106
|
+
|
107
|
+
@default_action ||= from_superclass(:default_action)
|
97
108
|
end
|
98
109
|
|
99
110
|
# Adds +action_names+ to the list of valid actions for this resource.
|
100
111
|
def self.actions(*action_names)
|
101
|
-
|
112
|
+
if action_names.empty?
|
113
|
+
defined?(@actions) ? @actions : from_superclass(:actions, []).dup
|
114
|
+
else
|
115
|
+
# BC-compat way for checking if actions have already been defined
|
116
|
+
if defined?(@actions)
|
117
|
+
@actions.push(*action_names)
|
118
|
+
else
|
119
|
+
@actions = action_names
|
120
|
+
end
|
121
|
+
end
|
102
122
|
end
|
103
123
|
|
104
|
-
|
105
|
-
|
124
|
+
# @deprecated
|
125
|
+
def self.valid_actions(*args)
|
126
|
+
Chef::Log.warn("`valid_actions' is deprecated, please use actions `instead'!")
|
127
|
+
actions(*args)
|
106
128
|
end
|
107
129
|
|
108
130
|
# Set the run context on the class. Used to provide access to the node
|
@@ -119,12 +141,34 @@ class Chef
|
|
119
141
|
run_context.node
|
120
142
|
end
|
121
143
|
|
144
|
+
def self.lazy(&block)
|
145
|
+
DelayedEvaluator.new(&block)
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
# Get the value from the superclass, if it responds, otherwise return
|
151
|
+
# +nil+. Since class instance variables are **not** inherited upon
|
152
|
+
# subclassing, this is a required check to ensure Chef pulls the
|
153
|
+
# +default_action+ and other DSL-y methods when extending LWRP::Base.
|
154
|
+
def self.from_superclass(m, default = nil)
|
155
|
+
return default if superclass == Chef::Resource::LWRPBase
|
156
|
+
superclass.respond_to?(m) ? superclass.send(m) : default
|
157
|
+
end
|
158
|
+
|
122
159
|
# Default initializer. Sets the default action and allowed actions.
|
123
160
|
def initialize(name, run_context=nil)
|
124
161
|
super(name, run_context)
|
162
|
+
|
163
|
+
# Raise an exception if the resource_name was not defined
|
164
|
+
if self.class.resource_name.nil?
|
165
|
+
raise Chef::Exceptions::InvalidResourceSpecification,
|
166
|
+
"You must specify `resource_name'!"
|
167
|
+
end
|
168
|
+
|
125
169
|
@resource_name = self.class.resource_name.to_sym
|
126
170
|
@action = self.class.default_action
|
127
|
-
allowed_actions.push(self.class.
|
171
|
+
allowed_actions.push(self.class.actions).flatten!
|
128
172
|
end
|
129
173
|
|
130
174
|
end
|
data/lib/chef/version.rb
CHANGED
@@ -0,0 +1,90 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Serdar Sutay (<serdar@getchef.com>)
|
3
|
+
# Copyright:: Copyright 2014 Chef Software, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/win32/api'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
module ReservedNames::Win32
|
23
|
+
module API
|
24
|
+
module Net
|
25
|
+
extend Chef::ReservedNames::Win32::API
|
26
|
+
|
27
|
+
FILTER_TEMP_DUPLICATE_ACCOUNT = 0x0001
|
28
|
+
FILTER_NORMAL_ACCOUNT = 0x0002
|
29
|
+
FILTER_INTERDOMAIN_TRUST_ACCOUNT = 0x0008
|
30
|
+
FILTER_WORKSTATION_TRUST_ACCOUNT = 0x0010
|
31
|
+
FILTER_SERVER_TRUST_ACCOUNT = 0x0020
|
32
|
+
|
33
|
+
MAX_PREFERRED_LENGTH = 0xFFFF
|
34
|
+
|
35
|
+
NERR_Success = 0
|
36
|
+
|
37
|
+
ffi_lib "netapi32"
|
38
|
+
|
39
|
+
class USER_INFO_3 < FFI::Struct
|
40
|
+
layout :usri3_name, :LPWSTR,
|
41
|
+
:usri3_password, :LPWSTR,
|
42
|
+
:usri3_password_age, :DWORD,
|
43
|
+
:usri3_priv, :DWORD,
|
44
|
+
:usri3_home_dir, :LPWSTR,
|
45
|
+
:usri3_comment, :LPWSTR,
|
46
|
+
:usri3_flags, :DWORD,
|
47
|
+
:usri3_script_path, :LPWSTR,
|
48
|
+
:usri3_auth_flags, :DWORD,
|
49
|
+
:usri3_full_name, :LPWSTR,
|
50
|
+
:usri3_usr_comment, :LPWSTR,
|
51
|
+
:usri3_parms, :LPWSTR,
|
52
|
+
:usri3_workstations, :LPWSTR,
|
53
|
+
:usri3_last_logon, :DWORD,
|
54
|
+
:usri3_last_logoff, :DWORD,
|
55
|
+
:usri3_acct_expires, :DWORD,
|
56
|
+
:usri3_max_storage, :DWORD,
|
57
|
+
:usri3_units_per_week, :DWORD,
|
58
|
+
:usri3_logon_hours, :PBYTE,
|
59
|
+
:usri3_bad_pw_count, :DWORD,
|
60
|
+
:usri3_num_logons, :DWORD,
|
61
|
+
:usri3_logon_server, :LPWSTR,
|
62
|
+
:usri3_country_code, :DWORD,
|
63
|
+
:usri3_code_page, :DWORD,
|
64
|
+
:usri3_user_id, :DWORD,
|
65
|
+
:usri3_primary_group_id, :DWORD,
|
66
|
+
:usri3_profile, :LPWSTR,
|
67
|
+
:usri3_home_dir_drive, :LPWSTR,
|
68
|
+
:usri3_password_expired, :DWORD
|
69
|
+
end
|
70
|
+
|
71
|
+
# NET_API_STATUS NetUserEnum(
|
72
|
+
# _In_ LPCWSTR servername,
|
73
|
+
# _In_ DWORD level,
|
74
|
+
# _In_ DWORD filter,
|
75
|
+
# _Out_ LPBYTE *bufptr,
|
76
|
+
# _In_ DWORD prefmaxlen,
|
77
|
+
# _Out_ LPDWORD entriesread,
|
78
|
+
# _Out_ LPDWORD totalentries,
|
79
|
+
# _Inout_ LPDWORD resume_handle
|
80
|
+
# );
|
81
|
+
safe_attach_function :NetUserEnum, [ :LPCWSTR, :DWORD, :DWORD, :LPBYTE, :DWORD, :LPDWORD, :LPDWORD, :LPDWORD ], :DWORD
|
82
|
+
|
83
|
+
# NET_API_STATUS NetApiBufferFree(
|
84
|
+
# _In_ LPVOID Buffer
|
85
|
+
# );
|
86
|
+
safe_attach_function :NetApiBufferFree, [ :LPVOID ], :DWORD
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -17,11 +17,22 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'chef/win32/security'
|
20
|
+
require 'chef/win32/api/net'
|
21
|
+
require 'chef/win32/api/error'
|
22
|
+
|
23
|
+
require 'wmi-lite/wmi'
|
20
24
|
|
21
25
|
class Chef
|
22
26
|
module ReservedNames::Win32
|
23
27
|
class Security
|
24
28
|
class SID
|
29
|
+
include Chef::ReservedNames::Win32::API::Net
|
30
|
+
include Chef::ReservedNames::Win32::API::Error
|
31
|
+
|
32
|
+
class << self
|
33
|
+
include Chef::ReservedNames::Win32::API::Net
|
34
|
+
include Chef::ReservedNames::Win32::API::Error
|
35
|
+
end
|
25
36
|
|
26
37
|
def initialize(pointer, owner = nil)
|
27
38
|
@pointer = pointer
|
@@ -178,13 +189,11 @@ class Chef
|
|
178
189
|
SID.from_string_sid('S-1-5-32-544')
|
179
190
|
end
|
180
191
|
|
181
|
-
# Machine-specific, well-known SIDs
|
182
|
-
# TODO: don't use strings, dummy
|
183
192
|
def self.None
|
184
193
|
SID.from_account("#{::ENV['COMPUTERNAME']}\\None")
|
185
194
|
end
|
186
195
|
def self.Administrator
|
187
|
-
SID.from_account("#{::ENV['COMPUTERNAME']}
|
196
|
+
SID.from_account("#{::ENV['COMPUTERNAME']}\\#{SID.admin_account_name}")
|
188
197
|
end
|
189
198
|
def self.Guest
|
190
199
|
SID.from_account("#{::ENV['COMPUTERNAME']}\\Guest")
|
@@ -193,6 +202,47 @@ class Chef
|
|
193
202
|
def self.current_user
|
194
203
|
SID.from_account("#{::ENV['USERDOMAIN']}\\#{::ENV['USERNAME']}")
|
195
204
|
end
|
205
|
+
|
206
|
+
def self.admin_account_name
|
207
|
+
@admin_account_name ||= begin
|
208
|
+
admin_account_name = nil
|
209
|
+
|
210
|
+
# Call NetUserEnum to enumerate the users without hitting network
|
211
|
+
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa370652(v=vs.85).aspx
|
212
|
+
servername = nil # We are querying the local server
|
213
|
+
level = 3 # We want USER_INFO_3 structure which contains the SID
|
214
|
+
filter = FILTER_NORMAL_ACCOUNT # Only query the user accounts
|
215
|
+
bufptr = FFI::MemoryPointer.new(:pointer) # Buffer which will receive the data
|
216
|
+
prefmaxlen = MAX_PREFERRED_LENGTH # Let the system allocate the needed amount of memory
|
217
|
+
entriesread = FFI::Buffer.new(:long).write_long(0)
|
218
|
+
totalentries = FFI::Buffer.new(:long).write_long(0)
|
219
|
+
resume_handle = FFI::Buffer.new(:long).write_long(0)
|
220
|
+
|
221
|
+
status = ERROR_MORE_DATA
|
222
|
+
|
223
|
+
while(status == ERROR_MORE_DATA) do
|
224
|
+
status = NetUserEnum(servername, level, filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle)
|
225
|
+
|
226
|
+
if (status == NERR_Success || status == ERROR_MORE_DATA)
|
227
|
+
entriesread.read_long.times.collect do |i|
|
228
|
+
user_info = USER_INFO_3.new(bufptr.read_pointer + i * USER_INFO_3.size)
|
229
|
+
# Check if the account is the Administrator account
|
230
|
+
# RID for the Administrator account is always 500 and it's privilage is set to USER_PRIV_ADMIN
|
231
|
+
if user_info[:usri3_user_id] == 500 && user_info[:usri3_priv] == 2 # USER_PRIV_ADMIN (2) - Administrator
|
232
|
+
admin_account_name = user_info[:usri3_name].read_wstring
|
233
|
+
break
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# Free the memory allocated by the system
|
238
|
+
NetApiBufferFree(bufptr.read_pointer)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
raise "Can not determine the administrator account name." if admin_account_name.nil?
|
243
|
+
admin_account_name
|
244
|
+
end
|
245
|
+
end
|
196
246
|
end
|
197
247
|
end
|
198
248
|
end
|