File: ldap.rb

package info (click to toggle)
puppet-agent 7.23.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 19,092 kB
  • sloc: ruby: 245,074; sh: 456; makefile: 38; xml: 33
file content (132 lines) | stat: -rw-r--r-- 3,728 bytes parent folder | download
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
require_relative '../../../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 in `puppet.conf`, including `ldapbase`.  You will
    almost definitely need settings for `ldapuser` and `ldappassword` in order
    for your clients to 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_shell

  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|
    cn[0].split(/\s+/)[-1]
  end

  # Find the next uid after the current largest uid.
  provider = self
  manager.generates(:uidNumber).with do
    largest = 500
    existing = provider.manager.search
    if existing
      existing.each do |hash|
        value = hash[:uid]
        next unless value
        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 value.is_a?(Integer)

    @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]
      result = group_manager.search("memberUid=#{name}")
      unless result
        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|
      ldap_group = group_manager.find(group)
      self.fail "Could not find ldap group #{group}" unless ldap_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