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
|
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
if num > largest
largest = num
end
end
end
largest + 1
end
# Convert our gid to a group name, if necessary.
def gid=(value)
unless [Fixnum, Bignum].include?(value.class)
value = group2id(value)
end
@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=%s" % name)
return @property_hash[:groups] = :absent
end
return @property_hash[:groups] = result.collect { |r| r[:name] }.join(",")
end
return @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 %s" % 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
|