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:
parent
762f639e63
commit
9bddb7b087
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user