class OpenNebula::LdapAuth

Public Class Methods

new(options) click to toggle source
# File lib/opennebula/ldap_auth.rb, line 37
def initialize(options)
    @options={
        :host               => 'localhost',
        :port               => 389,
        :user               => nil,
        :password           => nil,
        :base               => nil,
        :group_base         => nil,
        :auth_method        => :simple,
        :user_field         => 'cn',
        :user_group_field   => 'dn',
        :group_field        => 'member',
        :mapping_generate   => true,
        :mapping_timeout    => 300,
        :mapping_filename   => 'server1.yaml',
        :mapping_key        => 'GROUP_DN',
        :mapping_default    => 1,
        :attributes         => [ "memberOf" ],
        :rfc2307bis         => true,
        :group_admin_group_dn => nil
    }.merge(options)

    ops={}

    if @options[:user]
        ops[:auth] = {
            :method => @options[:auth_method],
            :username => @options[:user],
            :password => @options[:password]
        }
    end

    # always fetch user_filed to compare whitespace diff
    @options[:attributes] << @options[:user_field]

    # fetch the user group field only if we need that
    if @options[:group] or !@options[:rfc2307bis]
        @options[:attributes] << @options[:user_group_field]
    end

    ops[:host]=@options[:host] if @options[:host]
    ops[:port]=@options[:port].to_i if @options[:port]
    ops[:encryption]=@options[:encryption] if @options[:encryption]

    @options[:mapping_file_path] = VAR_LOCATION + @options[:mapping_filename]
    generate_mapping if @options[:mapping_generate]
    load_mapping

    @ldap=Net::LDAP.new(ops)
end

Public Instance Methods

authenticate(user, password) click to toggle source
# File lib/opennebula/ldap_auth.rb, line 180
def authenticate(user, password)
    ldap=@ldap.clone

    auth={
        :method => @options[:auth_method],
        :username => user,
        :password => password
    }

    if ldap.bind(auth)
        true
    else
        false
    end
end
find_user(name) click to toggle source
# File lib/opennebula/ldap_auth.rb, line 136
def find_user(name)
    filter = Net::LDAP::Filter.equals(@options[:user_field], name)

    result = @ldap.search(
        :base       => @options[:base],
        :attributes => @options[:attributes],
        :filter     => filter
    )

    if result && result.first
        @user = result.first

        [@user.dn,
         @user[@options[:user_field]].first,
         @user[@options[:user_group_field]]]
    else
        result=@ldap.search(:base => name)

        if result && result.first
            @user = result.first
            [name,
             @user[@options[:user_field]].first,
             @user[@options[:user_group_field]]]
        else
            [nil, nil, nil]
        end
    end
end
generate_mapping() click to toggle source
# File lib/opennebula/ldap_auth.rb, line 88
def generate_mapping
    file=@options[:mapping_file_path]
    generate = false

    if File.exists?(file)
        stat = File.stat(file)
        age = Time.now.to_i - stat.mtime.to_i
        generate = true if age > @options[:mapping_timeout]
    else
        generate = true
    end

    return if !generate

    client = OpenNebula::Client.new
    group_pool = OpenNebula::GroupPool.new(client)
    group_pool.info

    groups = group_pool.to_hash['']
    groups=[group_pool.get_hash['GROUP_POOL']['GROUP']].flatten

    yaml={}

    groups.each do |group|
        if group['TEMPLATE'] && group['TEMPLATE'][@options[:mapping_key]]
            yaml[group['TEMPLATE'][@options[:mapping_key]]] = group['ID']
        end
    end

    File.open(file, 'w') do |f|
        f.write(yaml.to_yaml)
    end
end
get_groups() click to toggle source
# File lib/opennebula/ldap_auth.rb, line 200
def get_groups
    if @options[:rfc2307bis]
        ldap_groups = [@user['memberOf']].flatten
    else
        group_base = @options[:group_base] ? @options[:group_base] : @options[:base]
        filter = Net::LDAP::Filter.equals(@options[:group_field], @user[@options[:user_group_field]].first)
        ldap_groups = @ldap.search(
            :base       => group_base,
            :attributes => [ "dn" ],
            :filter     => filter
        ).map! { |entry| entry.dn }
    end

    groups = []
    ldap_groups.each do |group|
        if (g = in_hash_ignore_case?(@mapping, group))
            if ldap_groups.any? {
                    |s| s.casecmp(@options[:group_admin_group_dn])==0
            }
                groups << "*#{@mapping[g]}"
            else
                groups << @mapping[g]
            end
        end
    end

    groups.delete(false)
    groups.compact.uniq
end
in_hash_ignore_case?(hash, key) click to toggle source
# File lib/opennebula/ldap_auth.rb, line 196
def in_hash_ignore_case?(hash, key)
    return hash.keys.find {|k| key.downcase == k.downcase}
end
is_in_group?(user, group) click to toggle source
# File lib/opennebula/ldap_auth.rb, line 165
def is_in_group?(user, group)
    username = Net::LDAP::Filter.escape(
        user.first.force_encoding(Encoding::UTF_8))
    result=@ldap.search(
                :base   => group,
                :attributes => [@options[:group_field]],
                :filter => "(#{@options[:group_field]}=#{username})")

    if result && result.first
        true
    else
        false
    end
end
load_mapping() click to toggle source
# File lib/opennebula/ldap_auth.rb, line 122
def load_mapping
    file=@options[:mapping_file_path]

    @mapping = {}

    if File.exists?(file)
        @mapping = YAML.load(File.read(file))
    end

    if @mapping.class != Hash
        @mapping = {}
    end
end