mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-11 05:17:41 +03:00
Feature #687: ACL Manager looks for rules that apply to any of the user's groups
This commit is contained in:
parent
a0a51efb55
commit
303db36d95
@ -114,6 +114,29 @@ public:
|
||||
private:
|
||||
multimap<long long, AclRule*> acl_rules;
|
||||
|
||||
/**
|
||||
* Gets all rules that apply to the user_req and, if any of them grants
|
||||
* permission, returns true.
|
||||
*
|
||||
* @param user_req user/group id and flags
|
||||
* @param resource_oid_req 64 bit request, ob. type and individual oid
|
||||
* @param resource_gid_req 64 bit request, ob. type and group id
|
||||
* @param resource_all_req 64 bit request, ob. type and all flag
|
||||
* @param rights_req Requested rights
|
||||
* @param individual_obj_type Mask with ob. type and individual flags
|
||||
* @param group_obj_type Mask with ob. type and gropu flags
|
||||
*
|
||||
* @return true if any rule grants permission
|
||||
*/
|
||||
bool match_rules(
|
||||
long long user_req,
|
||||
long long resource_oid_req,
|
||||
long long resource_gid_req,
|
||||
long long resource_all_req,
|
||||
long long rights_req,
|
||||
long long individual_obj_type,
|
||||
long long group_obj_type);
|
||||
|
||||
// ----------------------------------------
|
||||
// DataBase implementation variables
|
||||
// ----------------------------------------
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define AUTH_MANAGER_H_
|
||||
|
||||
#include <time.h>
|
||||
#include <set>
|
||||
|
||||
#include "MadManager.h"
|
||||
#include "ActionManager.h"
|
||||
@ -259,10 +260,11 @@ private:
|
||||
class AuthRequest : public ActionListener
|
||||
{
|
||||
public:
|
||||
AuthRequest(int _uid):
|
||||
AuthRequest(int _uid, set<int> _gids):
|
||||
result(false),
|
||||
timeout(false),
|
||||
uid(_uid),
|
||||
gids(_gids),
|
||||
time_out(0),
|
||||
self_authorize(true)
|
||||
{
|
||||
@ -460,6 +462,11 @@ private:
|
||||
*/
|
||||
int uid;
|
||||
|
||||
/**
|
||||
* The user groups ID set
|
||||
*/
|
||||
set<int> gids;
|
||||
|
||||
/**
|
||||
* Timeout for this request
|
||||
*/
|
||||
|
@ -60,9 +60,11 @@ protected:
|
||||
/* ------------------- Attributes of the Request ---------------------- */
|
||||
|
||||
int uid; /**< id of the user performing the request */
|
||||
|
||||
|
||||
int gid; /**< id of the user's group */
|
||||
|
||||
set<int> group_ids; /**< set of user's group ids */
|
||||
|
||||
PoolSQL * pool; /**< Pool of objects */
|
||||
|
||||
string method_name; /**< The name of the XML-RPC method */
|
||||
|
@ -104,7 +104,7 @@ class VirtualNetworkAllocate: public RequestManagerAllocate
|
||||
{
|
||||
public:
|
||||
VirtualNetworkAllocate():
|
||||
RequestManagerAllocate("VirtualNetworkInfo",
|
||||
RequestManagerAllocate("VirtualNetworkAllocate",
|
||||
"Allocates a new virtual network",
|
||||
"A:ss",
|
||||
true)
|
||||
@ -200,7 +200,7 @@ class HostAllocate : public RequestManagerAllocate
|
||||
{
|
||||
public:
|
||||
HostAllocate():
|
||||
RequestManagerAllocate("HostInfo",
|
||||
RequestManagerAllocate("HostAllocate",
|
||||
"Allocates a new host",
|
||||
"A:sssss",
|
||||
false)
|
||||
@ -225,7 +225,7 @@ class UserAllocate: public RequestManagerAllocate
|
||||
{
|
||||
public:
|
||||
UserAllocate():
|
||||
RequestManagerAllocate("UserInfo",
|
||||
RequestManagerAllocate("UserAllocate",
|
||||
"Returns user information",
|
||||
"A:sss",
|
||||
false)
|
||||
|
@ -102,9 +102,12 @@ public:
|
||||
* @param session, colon separated username and password string
|
||||
* @param uid of the user if authN succeeded -1 otherwise
|
||||
* @param gid of the user if authN succeeded -1 otherwise
|
||||
* @param group_ids the user groups if authN succeeded, is empty otherwise
|
||||
* @return false if authn failed, true otherwise
|
||||
*/
|
||||
bool authenticate(const string& session, int& uid, int& gid);
|
||||
bool authenticate(const string& session, int& uid, int& gid,
|
||||
set<int>& group_ids);
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether there is a user with given username/password or not
|
||||
|
@ -64,9 +64,10 @@ const bool AclManager::authorize(int uid, const set<int> &user_groups,
|
||||
bool auth = false;
|
||||
|
||||
// Build masks for request
|
||||
long long user_req = AclRule::INDIVIDUAL_ID + uid;
|
||||
long long user_req;
|
||||
long long resource_oid_req = obj_type + AclRule::INDIVIDUAL_ID + obj_id;
|
||||
long long resource_gid_req = obj_type + AclRule::GROUP_ID + obj_gid;
|
||||
long long resource_all_req = obj_type + AclRule::ALL_ID;
|
||||
long long rights_req = op;
|
||||
|
||||
long long individual_obj_type =
|
||||
@ -75,12 +76,82 @@ const bool AclManager::authorize(int uid, const set<int> &user_groups,
|
||||
long long group_obj_type =
|
||||
( obj_type | AclRule::GROUP_ID | 0xFFFFFFFF );
|
||||
|
||||
AclRule request_rule(user_req, resource_oid_req, rights_req);
|
||||
|
||||
|
||||
AclRule request_rule(AclRule::INDIVIDUAL_ID + uid, resource_oid_req, rights_req);
|
||||
oss << "Request " << request_rule.to_str();
|
||||
NebulaLog::log("ACL",Log::DEBUG,oss);
|
||||
|
||||
|
||||
// TODO: This only works for individual uid
|
||||
// Look for rules that apply to everyone
|
||||
|
||||
user_req = AclRule::ALL_ID;
|
||||
auth = match_rules(user_req, resource_oid_req, resource_gid_req,
|
||||
resource_all_req, rights_req, individual_obj_type, group_obj_type);
|
||||
|
||||
if ( auth == true )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Look for rules that apply to the individual user id
|
||||
user_req = AclRule::INDIVIDUAL_ID + uid;
|
||||
|
||||
auth = match_rules(user_req, resource_oid_req, resource_gid_req,
|
||||
resource_all_req, rights_req, individual_obj_type, group_obj_type);
|
||||
|
||||
if ( auth == true )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Look for rules that apply to each one of the user's groups
|
||||
|
||||
set<int>::iterator g_it;
|
||||
|
||||
for (g_it = user_groups.begin(); g_it != user_groups.end(); g_it++)
|
||||
{
|
||||
user_req = AclRule::GROUP_ID + *g_it;
|
||||
|
||||
auth = match_rules(user_req, resource_oid_req, resource_gid_req,
|
||||
resource_all_req, rights_req, individual_obj_type,
|
||||
group_obj_type);
|
||||
|
||||
if ( auth == true )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
oss.str("No more rules, permission not granted ");
|
||||
NebulaLog::log("ACL",Log::DEBUG,oss);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
bool AclManager::match_rules(
|
||||
long long user_req,
|
||||
long long resource_oid_req,
|
||||
long long resource_gid_req,
|
||||
long long resource_all_req,
|
||||
long long rights_req,
|
||||
long long individual_obj_type,
|
||||
long long group_obj_type)
|
||||
|
||||
{
|
||||
bool auth;
|
||||
ostringstream oss;
|
||||
|
||||
multimap<long long, AclRule *>::iterator it;
|
||||
|
||||
pair<multimap<long long, AclRule *>::iterator,
|
||||
multimap<long long, AclRule *>::iterator> index;
|
||||
|
||||
index = acl_rules.equal_range( user_req );
|
||||
|
||||
for ( it = index.first; it != index.second; it++)
|
||||
@ -90,15 +161,19 @@ const bool AclManager::authorize(int uid, const set<int> &user_groups,
|
||||
NebulaLog::log("ACL",Log::DEBUG,oss);
|
||||
|
||||
auth =
|
||||
(
|
||||
// Rule's object type and individual object ID match
|
||||
( ( it->second->resource & individual_obj_type ) == resource_oid_req )
|
||||
||
|
||||
// Or rule's object type and group object ID match
|
||||
( ( it->second->resource & group_obj_type ) == resource_gid_req )
|
||||
)
|
||||
&&
|
||||
( ( it->second->rights & rights_req ) == rights_req );
|
||||
// Rule grants the requested rights
|
||||
( ( it->second->rights & rights_req ) == rights_req )
|
||||
&&
|
||||
(
|
||||
// Rule grants permission for all objects of this type
|
||||
( it->second->resource == resource_all_req )
|
||||
||
|
||||
// Or rule's object type and group object ID match
|
||||
( ( it->second->resource & group_obj_type ) == resource_gid_req )
|
||||
||
|
||||
// Or rule's object type and individual object ID match
|
||||
( ( it->second->resource & individual_obj_type ) == resource_oid_req )
|
||||
);
|
||||
|
||||
if ( auth == true )
|
||||
{
|
||||
@ -109,9 +184,6 @@ const bool AclManager::authorize(int uid, const set<int> &user_groups,
|
||||
}
|
||||
}
|
||||
|
||||
oss.str("No more rules, permission not granted ");
|
||||
NebulaLog::log("ACL",Log::DEBUG,oss);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -80,13 +80,10 @@ void AuthRequest::add_auth(Object ob,
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO, the set of object ids is needed
|
||||
set<int> emtpy_set;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
AclManager* aclm = nd.get_aclm();
|
||||
|
||||
auth = aclm->authorize(uid, emtpy_set, ob, ob_id_int, ob_gid, op);
|
||||
auth = aclm->authorize(uid, gids, ob, ob_id_int, ob_gid, op);
|
||||
}
|
||||
|
||||
self_authorize = self_authorize && auth;
|
||||
|
@ -120,7 +120,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
command :chgrp, chgrp_desc, [:range, :userid_list], :groupid do
|
||||
helper.perform_actions(args[0],options,"Group changed") do |user|
|
||||
user.chown(-1, args[1].to_i)
|
||||
user.chgrp(args[1].to_i)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -33,7 +33,7 @@ void Request::execute(
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG, method_name + " method invoked");
|
||||
|
||||
if ( upool->authenticate(session, uid, gid) == false )
|
||||
if ( upool->authenticate(session, uid, gid, group_ids) == false )
|
||||
{
|
||||
failure_response(AUTHENTICATION, authenticate_error());
|
||||
}
|
||||
@ -81,7 +81,7 @@ bool Request::basic_authorization(int oid)
|
||||
object->unlock();
|
||||
}
|
||||
|
||||
AuthRequest ar(uid);
|
||||
AuthRequest ar(uid, group_ids);
|
||||
|
||||
ar.add_auth(auth_object, oid, ogid, auth_op, ouid, pub);
|
||||
|
||||
|
@ -46,37 +46,6 @@ void RequestManagerAcl::request_execute(xmlrpc_c::paramList const& paramList)
|
||||
iss >> hex >> rights;
|
||||
|
||||
|
||||
|
||||
// TODO, debug
|
||||
/*
|
||||
int iu, id, it;
|
||||
|
||||
iss.clear();
|
||||
iss.str( xmlrpc_c::value_string(paramList.getString(1)) );
|
||||
iss >> iu;
|
||||
|
||||
iss.clear();
|
||||
iss.str( xmlrpc_c::value_string(paramList.getString(2)) );
|
||||
iss >> id;
|
||||
|
||||
iss.clear();
|
||||
iss.str( xmlrpc_c::value_string(paramList.getString(3)) );
|
||||
iss >> it;
|
||||
|
||||
|
||||
|
||||
ostringstream oss;
|
||||
string u = xmlrpc_c::value_string(paramList.getString(1));
|
||||
string d = xmlrpc_c::value_string(paramList.getString(2));
|
||||
string t = xmlrpc_c::value_string(paramList.getString(3));
|
||||
|
||||
oss << "\n";
|
||||
oss << "User : " << u << ", " << iu << ", dec: " << dec << user << "\n";
|
||||
oss << "Resource : " << d << ", " << id << ", dec: " << dec << resource << "\n";
|
||||
oss << "Rights : " << t << ", " << it << ", dec: " << dec << rights << "\n";
|
||||
NebulaLog::log("ACL-RM",Log::DEBUG,oss);
|
||||
*/
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
aclm = nd.get_aclm();
|
||||
|
||||
|
@ -30,7 +30,7 @@ bool RequestManagerAllocate::allocate_authorization(Template * tmpl)
|
||||
return true;
|
||||
}
|
||||
|
||||
AuthRequest ar(uid);
|
||||
AuthRequest ar(uid, group_ids);
|
||||
|
||||
if ( tmpl == 0 )
|
||||
{
|
||||
@ -62,7 +62,8 @@ bool VirtualMachineAllocate::allocate_authorization(Template * tmpl)
|
||||
return true;
|
||||
}
|
||||
|
||||
AuthRequest ar(uid);
|
||||
AuthRequest ar(uid, group_ids);
|
||||
|
||||
string t64;
|
||||
|
||||
VirtualMachineTemplate * ttmpl = static_cast<VirtualMachineTemplate *>(tmpl);
|
||||
|
@ -55,7 +55,7 @@ void VMTemplateInstantiate::request_execute(xmlrpc_c::paramList const& paramList
|
||||
|
||||
if ( uid != 0 )
|
||||
{
|
||||
AuthRequest ar(uid);
|
||||
AuthRequest ar(uid, group_ids);
|
||||
|
||||
ar.add_auth(auth_object, id, ogid, auth_op, ouid, false);
|
||||
|
||||
|
@ -45,7 +45,7 @@ bool RequestManagerVirtualMachine::vm_authorization(int oid, int hid, ImageTempl
|
||||
|
||||
object->unlock();
|
||||
|
||||
AuthRequest ar(uid);
|
||||
AuthRequest ar(uid, group_ids);
|
||||
|
||||
ar.add_auth(auth_object, oid, ogid, auth_op, ouid, false);
|
||||
|
||||
|
@ -190,7 +190,9 @@ error_common:
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
bool UserPool::authenticate(const string& session, int& user_id, int& group_id)
|
||||
//bool UserPool::authenticate(const string& session, int& user_id, int& group_id)
|
||||
bool UserPool::authenticate(const string& session, int& user_id, int& group_id,
|
||||
set<int>& group_ids)
|
||||
{
|
||||
map<string, int>::iterator index;
|
||||
|
||||
@ -224,6 +226,8 @@ bool UserPool::authenticate(const string& session, int& user_id, int& group_id)
|
||||
uid = user->oid;
|
||||
gid = user->gid;
|
||||
|
||||
group_ids = user->get_groups();
|
||||
|
||||
user->unlock();
|
||||
}
|
||||
else //External User
|
||||
@ -233,7 +237,7 @@ bool UserPool::authenticate(const string& session, int& user_id, int& group_id)
|
||||
gid = -1;
|
||||
}
|
||||
|
||||
AuthRequest ar(uid);
|
||||
AuthRequest ar(uid, group_ids);
|
||||
|
||||
ar.add_authenticate(username,u_pass,secret);
|
||||
|
||||
@ -302,6 +306,7 @@ bool UserPool::authenticate(const string& session, int& user_id, int& group_id)
|
||||
}
|
||||
else
|
||||
{
|
||||
group_ids.insert( GroupPool::USERS_ID );
|
||||
group_id = GroupPool::USERS_ID;
|
||||
result = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user