puppet/user/scripts/update-virtual.rb
2013-11-12 09:50:05 +02:00

104 lines
3 KiB
Ruby
Executable file

require "set"
require "uri"
require "ldap"
conn = nil
basedn = nil
File.readlines("/etc/openldap/ldap.conf").each do |line|
line = line.strip
next if line.empty? or line.start_with?("#")
line = line.split
if line[0] == "BASE"
basedn = line[1]
elsif line[0] == "URI"
line.shift
line.each do |uri|
uri = URI.parse(uri)
begin
if uri.scheme == "ldaps"
uri.port = 636 unless uri.port
conn = LDAP::SSLConn.new(uri.host, uri.port)
else
uri.port = 389 unless uri.port
conn = LDAP::Conn.new(uri.host, uri.port)
end
conn.bind
break
rescue LDAP::ResultError
next
end
end
end
end
virtual = "class user::virtual {\n"
filter = "objectClass=posixAccount"
attrib = %w(uid uidNumber gidNumber gecos homeDirectory loginShell)
conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrib) do |entry|
dn = entry.get_dn
uid = entry["uid"].first
uidnumber = entry["uidNumber"].first
gidnumber = entry["gidNumber"].first
primarygroup = nil
groups = Set.new
filter = "(&(objectClass=posixGroup)(gidNumber=#{gidnumber}))"
conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ["cn"]) do |group|
primarygroup = group["cn"].first
end
continue if primarygroup.nil?
filter = "(&(objectClass=posixGroup)(|(uniqueMember=#{dn})(memberUid=#{uid})))"
conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ["cn"]) do |group|
groups << group["cn"].first
end
comment = entry["gecos"] ? entry["gecos"].first : entry["uid"].first
shell = entry["loginShell"] ? entry["loginShell"].first : "/bin/bash"
home = entry["homeDirectory"].first
virtual << <<-EOF
@user::add { "#{uid}":
uid => "#{uidnumber}",
gid => "#{gidnumber}",
comment => "#{comment}",
home => "#{home}",
shell => "#{shell}",
EOF
unless groups.empty?
virtual << " groups => $::operatingsystem ? {\n"
virtual << " \"openbsd\" => [ "
groups.sort.each { |group| virtual << "\"#{group}\", " }
virtual << "\"wheel\", " if groups.include?("sysadm")
virtual << "],\n default => [ "
groups.sort.each { |group| virtual << "\"#{group}\", " }
virtual << "],\n },\n"
end
virtual << " require => [\n"
virtual << " Group[\"#{primarygroup}\"],\n"
groups.sort.each { |group| virtual << " Group[\"#{group}\"],\n" }
virtual << " ],\n }\n"
end
filter = "objectClass=posixGroup"
attrib = %w(cn gidNumber memberUid uniqueMember)
conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrib) do |entry|
cn = entry["cn"].first
gid = entry["gidNumber"].first
virtual << <<-EOF
@group { "#{cn}":
ensure => present,
gid => "#{gid}",
}
EOF
end
puts virtual, "\n}"