1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
require_relative '../../../puppet/util/windows'
Puppet::Type.type(:user).provide :windows_adsi do
desc "Local user management for Windows."
defaultfor :operatingsystem => :windows
confine :operatingsystem => :windows
has_features :manages_homedir, :manages_passwords, :manages_roles
def initialize(value={})
super(value)
@deleted = false
end
def user
@user ||= Puppet::Util::Windows::ADSI::User.new(@resource[:name])
end
def roles
Puppet::Util::Windows::User::get_rights(@resource[:name])
end
def roles=(value)
current = roles.split(',')
should = value.split(',')
add_list = should - current
Puppet::Util::Windows::User::set_rights(@resource[:name], add_list) unless add_list.empty?
if @resource[:role_membership] == :inclusive
remove_list = current - should
Puppet::Util::Windows::User::remove_rights(@resource[:name], remove_list) unless remove_list.empty?
end
end
def groups
@groups ||= Puppet::Util::Windows::ADSI::Group.name_sid_hash(user.groups)
@groups.keys
end
def groups=(groups)
user.set_groups(groups, @resource[:membership] == :minimum)
end
def groups_insync?(current, should)
return false unless current
# By comparing account SIDs we don't have to worry about case
# sensitivity, or canonicalization of account names.
# Cannot use munge of the group property to canonicalize @should
# since the default array_matching comparison is not commutative
# dupes automatically weeded out when hashes built
current_groups = Puppet::Util::Windows::ADSI::Group.name_sid_hash(current)
specified_groups = Puppet::Util::Windows::ADSI::Group.name_sid_hash(should)
current_sids = current_groups.keys.to_a
specified_sids = specified_groups.keys.to_a
if @resource[:membership] == :inclusive
current_sids.sort == specified_sids.sort
else
(specified_sids & current_sids) == specified_sids
end
end
def groups_to_s(groups)
return '' if groups.nil? || !groups.kind_of?(Array)
groups = groups.map do |group_name|
sid = Puppet::Util::Windows::SID.name_to_principal(group_name)
if sid.account =~ /\\/
account, _ = Puppet::Util::Windows::ADSI::Group.parse_name(sid.account)
else
account = sid.account
end
resource.debug("#{sid.domain}\\#{account} (#{sid.sid})")
"#{sid.domain}\\#{account}"
end
return groups.join(',')
end
def create
@user = Puppet::Util::Windows::ADSI::User.create(@resource[:name])
@user.password = @resource[:password]
@user.commit
[:comment, :home, :groups].each do |prop|
send("#{prop}=", @resource[prop]) if @resource[prop]
end
if @resource.managehome?
Puppet::Util::Windows::User.load_profile(@resource[:name], @resource[:password])
end
end
def exists?
Puppet::Util::Windows::ADSI::User.exists?(@resource[:name])
end
def delete
# lookup sid before we delete account
sid = uid if @resource.managehome?
Puppet::Util::Windows::ADSI::User.delete(@resource[:name])
if sid
Puppet::Util::Windows::ADSI::UserProfile.delete(sid)
end
@deleted = true
end
# Only flush if we created or modified a user, not deleted
def flush
@user.commit if @user && !@deleted
end
def comment
user['Description']
end
def comment=(value)
user['Description'] = value
end
def home
user['HomeDirectory']
end
def home=(value)
user['HomeDirectory'] = value
end
def password
# avoid a LogonUserW style password check when the resource is not yet
# populated with a password (as is the case with `puppet resource user`)
return nil if @resource[:password].nil?
user.password_is?( @resource[:password] ) ? @resource[:password] : nil
end
def password=(value)
if user.disabled?
info _("The user account '%s' is disabled; The password will still be changed" % @resource[:name])
elsif user.locked_out?
info _("The user account '%s' is locked out; The password will still be changed" % @resource[:name])
elsif user.expired?
info _("The user account '%s' is expired; The password will still be changed" % @resource[:name])
end
user.password = value
end
def uid
Puppet::Util::Windows::SID.name_to_sid(@resource[:name])
end
def uid=(value)
fail "uid is read-only"
end
[:gid, :shell].each do |prop|
define_method(prop) { nil }
define_method("#{prop}=") do |v|
fail "No support for managing property #{prop} of user #{@resource[:name]} on Windows"
end
end
def self.instances
Puppet::Util::Windows::ADSI::User.map { |u| new(:ensure => :present, :name => u.name) }
end
end
|