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 groups = {} user_pp = [] group_pp = [] filter = "objectClass=posixAccount" attrib = %w(uid gidNumber) conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, attrib) do |entry| uid = entry["uid"].first next if uid.include?("$") # skip samba machine accounts dn = entry.get_dn gidnumber = entry["gidNumber"].first gids = Set.new # find primary group filter = "(&(objectClass=posixGroup)(gidNumber=#{gidnumber}))" conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ["cn"]) do |group| gid = group["cn"].first gids << gid groups[gid] = Set.new unless groups.has_key?(gid) groups[gid] << uid end # find supplementary groups filter = "(&(objectClass=posixGroup)(|(uniqueMember=#{dn})(memberUid=#{uid})))" conn.search(basedn, LDAP::LDAP_SCOPE_SUBTREE, filter, ["cn"]) do |group| gid = group["cn"].first gids << gid groups[gid] = Set.new unless groups.has_key?(gid) groups[gid] << uid end user_pp << "class user::user::#{uid} inherits user::virtual {\n\n" user_pp << " realize(User::Add[\"#{uid}\"])\n" gids.sort.each { |gid| user_pp << " realize(Group[\"#{gid}\"])\n" } user_pp << "\n}\n\n" end groups.each do |gid, uids| next if uids.length == 1 and uids.include?(gid) group_pp << "class user::group::%s {\n\n" % gid uids.sort.each { |uid| group_pp << " include user::user::#{uid}\n" } group_pp << "\n}\n\n" end puts user_pp if ARGV.include?("-u") puts group_pp if ARGV.include?("-g")