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
|
require 'puppet/provider/ldap'
Puppet::Type.type(:user).provide :ldap, :parent => Puppet::Provider::Ldap do
desc "User management via ``ldap``. This provider requires that you
have valid values for all of the ldap-related settings,
including ``ldapbase``. You will also almost definitely need settings
for ``ldapuser`` and ``ldappassword``, so that your clients can write
to ldap.
Note that this provider will automatically generate a UID for you if
you do not specify one, but it is a potentially expensive operation,
as it iterates across all existing users to pick the appropriate next
one."
confine :feature => :ldap, :false => (Puppet[:ldapuser] == "")
has_feature :manages_passwords
manages(:posixAccount, :person).at("ou=People").named_by(:uid).and.maps :name => :uid,
:password => :userPassword,
:comment => :cn,
:uid => :uidNumber,
:gid => :gidNumber,
:home => :homeDirectory,
:shell => :loginShell
# Use the last field of a space-separated array as
# the sn. LDAP requires a surname, for some stupid reason.
manager.generates(:sn).from(:cn).with do |cn|
x = 1
cn[0].split(/\s+/)[-1]
end
# Find the next uid after the current largest uid.
provider = self
manager.generates(:uidNumber).with do
largest = 500
if existing = provider.manager.search
existing.each do |hash|
next unless value = hash[:uid]
num = value[0].to_i
largest = num if num > largest
end
end
largest + 1
end
# Convert our gid to a group name, if necessary.
def gid=(value)
value = group2id(value) unless [Fixnum, Bignum].include?(value.class)
@property_hash[:gid] = value
end
# Find all groups this user is a member of in ldap.
def groups
# We want to cache the current result, so we know if we
# have to remove old values.
unless @property_hash[:groups]
unless result = group_manager.search("memberUid=#{name}")
return @property_hash[:groups] = :absent
end
return @property_hash[:groups] = result.collect { |r| r[:name] }.sort.join(",")
end
@property_hash[:groups]
end
# Manage the list of groups this user is a member of.
def groups=(values)
should = values.split(",")
if groups() == :absent
is = []
else
is = groups().split(",")
end
modes = {}
[is, should].flatten.uniq.each do |group|
# Skip it when they're in both
next if is.include?(group) and should.include?(group)
# We're adding a group.
modes[group] = :add and next unless is.include?(group)
# We're removing a group.
modes[group] = :remove and next unless should.include?(group)
end
modes.each do |group, form|
self.fail "Could not find ldap group #{group}" unless ldap_group = group_manager.find(group)
current = ldap_group[:members]
if form == :add
if current.is_a?(Array) and ! current.empty?
new = current + [name]
else
new = [name]
end
else
new = current - [name]
new = :absent if new.empty?
end
group_manager.update(group, {:ensure => :present, :members => current}, {:ensure => :present, :members => new})
end
end
# Convert a gropu name to an id.
def group2id(group)
Puppet::Type.type(:group).provider(:ldap).name2id(group)
end
private
def group_manager
Puppet::Type.type(:group).provider(:ldap).manager
end
def group_properties(values)
if values.empty? or values == :absent
{:ensure => :present}
else
{:ensure => :present, :members => values}
end
end
end
|