1
0
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:
Carlos Martín 2011-06-29 12:50:16 +02:00
parent a0a51efb55
commit 303db36d95
14 changed files with 144 additions and 65 deletions

View File

@ -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
// ----------------------------------------

View File

@ -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
*/

View File

@ -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 */

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}