mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-21 14:50:08 +03:00
Merge branch 'feature-3159'
This commit is contained in:
commit
0d5e96debf
@ -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
|
||||
|
||||
|
@ -686,10 +686,18 @@ bool UserPool::authenticate_external(const string& username,
|
||||
string mad_name;
|
||||
string mad_pass;
|
||||
string error_str;
|
||||
string tmp_str;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
AuthManager * authm = nd.get_authm();
|
||||
GroupPool * gpool = nd.get_gpool();
|
||||
|
||||
User* user;
|
||||
Group* group;
|
||||
|
||||
int gid = -1;
|
||||
|
||||
set<int>::iterator it;
|
||||
set<int> empty_set;
|
||||
|
||||
AuthRequest ar(-1,empty_set);
|
||||
@ -714,6 +722,11 @@ bool UserPool::authenticate_external(const string& username,
|
||||
|
||||
user_id = -1;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Parse driver response format is:
|
||||
// <driver> <username> <passwd> [gid...]
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
if ( is.good() )
|
||||
{
|
||||
is >> driver_name >> ws;
|
||||
@ -726,15 +739,69 @@ bool UserPool::authenticate_external(const string& username,
|
||||
|
||||
if ( !is.fail() )
|
||||
{
|
||||
getline(is, mad_pass);
|
||||
is >> mad_pass >> ws;
|
||||
}
|
||||
|
||||
while ( is.good() )
|
||||
{
|
||||
int tmp_gid;
|
||||
|
||||
is >> tmp_gid >> ws;
|
||||
|
||||
if ( is.fail() )
|
||||
{
|
||||
error_str = "One or more group IDs are malformed";
|
||||
goto auth_failure_user;
|
||||
}
|
||||
|
||||
if ( gpool->get(tmp_gid, false) == 0 )
|
||||
{
|
||||
error_str = "One or more group IDs do not exist";
|
||||
goto auth_failure_user;
|
||||
}
|
||||
|
||||
if ( gid == -1 ) //Keep the first id for primary group
|
||||
{
|
||||
gid = tmp_gid;
|
||||
}
|
||||
|
||||
group_ids.insert(tmp_gid);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Create the user, and set primary group
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
if ( gid == -1 )
|
||||
{
|
||||
group_id = GroupPool::USERS_ID;
|
||||
gname = GroupPool::USERS_NAME;
|
||||
|
||||
group_ids.insert( group_id );
|
||||
}
|
||||
else
|
||||
{
|
||||
group_id = gid;
|
||||
|
||||
group = gpool->get(group_id, true);
|
||||
|
||||
if( group == 0 )
|
||||
{
|
||||
error_str = "Primary Group no longer exist";
|
||||
goto auth_failure_user;
|
||||
}
|
||||
|
||||
gname = group->get_name();
|
||||
|
||||
group->unlock();
|
||||
}
|
||||
|
||||
if ( !is.fail() )
|
||||
{
|
||||
allocate(&user_id,
|
||||
GroupPool::USERS_ID,
|
||||
group_id,
|
||||
mad_name,
|
||||
GroupPool::USERS_NAME,
|
||||
gname,
|
||||
mad_pass,
|
||||
driver_name,
|
||||
true,
|
||||
@ -746,11 +813,41 @@ bool UserPool::authenticate_external(const string& username,
|
||||
goto auth_failure_user;
|
||||
}
|
||||
|
||||
group_id = GroupPool::USERS_ID;
|
||||
group_ids.insert( GroupPool::USERS_ID );
|
||||
//--------------------------------------------------------------------------
|
||||
// Add the user to the secondary groups
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
user = get(user_id,true);
|
||||
|
||||
if ( user == 0 )
|
||||
{
|
||||
error_str = "User object could not be retrieved";
|
||||
goto auth_failure_user;
|
||||
}
|
||||
|
||||
for(it = ++group_ids.begin(); it != group_ids.end(); it++)
|
||||
{
|
||||
group = gpool->get(*it, true);
|
||||
|
||||
if( group == 0 ) //Secondary group no longer exists
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
group->add_user(user_id);
|
||||
|
||||
gpool->update(group);
|
||||
|
||||
group->unlock();
|
||||
|
||||
user->add_group(*it);
|
||||
}
|
||||
|
||||
update(user);
|
||||
|
||||
user->unlock();
|
||||
|
||||
uname = mad_name;
|
||||
gname = GroupPool::USERS_NAME;
|
||||
|
||||
umask = User::get_default_umask();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user