1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-11 05:17:41 +03:00

feature #3159: map AD groups to ONE groups in ldap driver

Generates mapping file and returns a list of IDs of ONE mapped groups that
the user should belong.
This commit is contained in:
Javi Fontan 2014-08-22 12:55:05 +02:00 committed by Ruben S. Montero
parent 762f639e63
commit 9bddb7b087
3 changed files with 125 additions and 12 deletions

View File

@ -83,9 +83,21 @@ begin
end
if ldap.authenticate(user_name, secret)
groups = ldap.get_groups
if groups.empty?
if !server_conf[:mapping_default]
STDERR.puts "User does not belong to a mapped group"
authenticated = false
break
else
groups = [server_conf[:mapping_default]]
end
end
group_list = groups.join(' ')
escaped_user=URI_PARSER.escape(user)
escaped_secret=URI_PARSER.escape(user_name)
puts "ldap #{escaped_user} #{escaped_secret}"
puts "ldap #{escaped_user} #{escaped_secret} #{group_list}"
authenticated=true
break
else

View File

@ -49,6 +49,21 @@ server 1:
# user field that that is in in the group group_field, if not set 'dn' will be used
#:user_group_field: 'dn'
# Generate mapping file from group template info
:mapping_generate: true
# Seconds a mapping file remain untouched until the next regeneration
:mapping_timeout: 300
# Name of the mapping file in OpenNebula var diretory
:mapping_filename: server1.yaml
# Key from the OpenNebula template to map to an AD group
:mapping_key: GROUP_DN
# Default group ID used for users in an AD group not mapped
:mapping_default: 1
# this example server wont be called as it is not in the :order list
server 2:
:auth_method: :simple

View File

@ -15,22 +15,39 @@
# ---------------------------------------------------------------------------- #
require 'rubygems'
require 'opennebula'
require 'net/ldap'
require 'yaml'
if !defined?(ONE_LOCATION)
ONE_LOCATION=ENV["ONE_LOCATION"]
end
if !ONE_LOCATION
VAR_LOCATION="/var/lib/one/"
else
VAR_LOCATION=ONE_LOCATION+"/var/"
end
module OpenNebula; end
class OpenNebula::LdapAuth
def initialize(options)
@options={
:host => 'localhost',
:port => 389,
:user => nil,
:password => nil,
:base => nil,
:auth_method => :simple,
:user_field => 'cn',
:user_group_field => 'dn',
:group_field => 'member'
:host => 'localhost',
:port => 389,
:user => nil,
:password => nil,
: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
}.merge(options)
ops={}
@ -47,9 +64,61 @@ class OpenNebula::LdapAuth
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
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
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
def find_user(name)
begin
result=@ldap.search(
@ -57,12 +126,14 @@ class OpenNebula::LdapAuth
:filter => "#{@options[:user_field]}=#{name}")
if result && result.first
[result.first.dn, result.first[@options[:user_group_field]]]
@user = result.first
[@user.dn, @user[@options[:user_group_field]]]
else
result=@ldap.search(:base => name)
if result && result.first
[name, result.first[@options[:user_group_field]]]
@user = result.first
[name, @user[@options[:user_group_field]]]
else
[nil, nil]
end
@ -99,5 +170,20 @@ class OpenNebula::LdapAuth
false
end
end
def get_groups
groups = []
[@user['memberOf']].flatten.each do |group|
if @mapping[group]
groups << @mapping[group]
else
groups << @options[:mapping_default]
end
end
groups.delete(false)
groups.compact
end
end