Class: Chef::Util::Windows::NetUser

Inherits:
Chef::Util::Windows show all
Defined in:
lib/chef/util/windows/net_user.rb

Overview

wrapper around a subset of the NetUser* APIs. nothing Chef specific, but not complete enough to be its own gem, so util for now.

Constant Summary collapse

LOGON32_PROVIDER_DEFAULT =
Security::LOGON32_PROVIDER_DEFAULT
LOGON32_LOGON_NETWORK =
Security::LOGON32_LOGON_NETWORK

Instance Method Summary collapse

Constructor Details

#initialize(username) ⇒ NetUser

Returns a new instance of NetUser.


89
90
91
# File 'lib/chef/util/windows/net_user.rb', line 89

def initialize(username)
  @username = username
end

Instance Method Details

#add(args) ⇒ Object


121
122
123
124
125
# File 'lib/chef/util/windows/net_user.rb', line 121

def add(args)
  transformed_args = transform_usri3(args)
  NetUser.net_user_add_l3(nil, transformed_args)
  NetUser.net_local_group_add_member(nil, Chef::ReservedNames::Win32::Security::SID.BuiltinUsers., args[:name])
end

#check_enabledObject


170
171
172
# File 'lib/chef/util/windows/net_user.rb', line 170

def check_enabled
  (get_info[:flags] & NetUser::UF_ACCOUNTDISABLE) != 0
end

#deleteObject


144
145
146
147
148
# File 'lib/chef/util/windows/net_user.rb', line 144

def delete
  NetUser.net_user_del(nil, @username)
rescue Chef::Exceptions::Win32APIError => e
  raise ArgumentError, e
end

#disable_accountObject


150
151
152
153
154
155
156
157
158
# File 'lib/chef/util/windows/net_user.rb', line 150

def 
  user_modify do |user|
    user[:flags] |= NetUser::UF_ACCOUNTDISABLE
    # This does not set the password to nil. It (for some reason) means to ignore updating the field.
    # See similar behavior for the logon_hours field documented at
    # http://msdn.microsoft.com/en-us/library/windows/desktop/aa371338%28v=vs.85%29.aspx
    user[:password] = nil
  end
end

#enable_accountObject


160
161
162
163
164
165
166
167
168
# File 'lib/chef/util/windows/net_user.rb', line 160

def 
  user_modify do |user|
    user[:flags] &= ~NetUser::UF_ACCOUNTDISABLE
    # This does not set the password to nil. It (for some reason) means to ignore updating the field.
    # See similar behavior for the logon_hours field documented at
    # http://msdn.microsoft.com/en-us/library/windows/desktop/aa371338%28v=vs.85%29.aspx
    user[:password] = nil
  end
end

#get_infoObject


112
113
114
115
116
117
118
119
# File 'lib/chef/util/windows/net_user.rb', line 112

def get_info
  begin
    ui3 = NetUser.net_user_get_info_l3(nil, @username)
  rescue Chef::Exceptions::Win32APIError => e
    raise ArgumentError, e
  end
  usri3_to_hash(ui3)
end

#update(args) ⇒ Object


136
137
138
139
140
141
142
# File 'lib/chef/util/windows/net_user.rb', line 136

def update(args)
  user_modify do |user|
    args.each do |key, val|
      user[key] = val
    end
  end
end

#user_modify {|user| ... } ⇒ Object

FIXME: yard with @yield

Yields:

  • (user)

128
129
130
131
132
133
134
# File 'lib/chef/util/windows/net_user.rb', line 128

def user_modify
  user = get_info
  user[:last_logon] = user[:units_per_week] = 0 # ignored as per USER_INFO_3 doc
  user[:logon_hours] = nil # PBYTE field; \0 == no changes
  yield(user)
  set_info(user)
end

#validate_credentials(passwd) ⇒ Object

XXX for an extra painful alternative, see: support.microsoft.com/kb/180548


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/chef/util/windows/net_user.rb', line 96

def validate_credentials(passwd)
  token = Security.logon_user(@username, nil, passwd,
    LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT)
  true
rescue Chef::Exceptions::Win32APIError => e
  Chef::Log.trace(e)
  # we're only interested in the incorrect password failures
  if /System Error Code: 1326/.match?(e.to_s)
    return false
  end

  # all other exceptions will assume we cannot logon for a different reason
  Chef::Log.trace("Unable to login with the specified credentials. Assuming the credentials are valid.")
  true
end