1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-22 22:03:39 +03:00
* Chown method: destination user and group are checked, auth. manager request used.
  * New one.group.chown method.
  * New ObjectCollection class to store sets of IDs.
  * New RM user.addgroup user.delgroup methods, users and groups store a cross-reference ID set.
  * Clusters store a set of Host IDs. The RM part of the add/remove host functionality works, but should be re-done to avoid deadlocks.
  * Fix onedb schmea for template_pool table bug.
This commit is contained in:
Carlos Martín 2011-05-25 12:13:17 +02:00
parent b0ddfd382c
commit 6230001c56
29 changed files with 1247 additions and 184 deletions

View File

@ -19,36 +19,16 @@
#include "PoolSQL.h"
#include "Host.h"
#include "ObjectCollection.h"
using namespace std;
/**
* The Cluster class.
*/
class Cluster : public PoolObjectSQL
class Cluster : public PoolObjectSQL, public ObjectCollection
{
public:
/**
* Adds the host to this cluster
* @param host The host to add
*
* @return 0 on success
*/
/*
int add_host(Host * host)
{
return host->set_cluster(name);
};
*/
/**
* Removes the host from this cluster
* @param host The host to add
*
* @return 0 on success
*/
// May be needed in a future
// int remove_host(Host * host);
/**
* Function to write a Cluster on an output stream
@ -127,6 +107,17 @@ private:
* @return 0 on success
*/
int update(SqlDB *db);
// *************************************************************************
// Host IDs set
// *************************************************************************
/**
* Moves all hosts in this cluster to the default one. Must be called
* before the cluster is dropped.
*/
int set_default_cluster();
};
#endif /*CLUSTER_H_*/

View File

@ -34,17 +34,6 @@ public:
~ClusterPool(){};
/**
* Removes the host from the given cluster setting the default one.
* @param host The host to assign
*
* @return 0 on success
*/
int set_default_cluster(Host * host)
{
return host->set_cluster(ClusterPool::DEFAULT_CLUSTER_ID);
};
/**
* Cluster name for the default cluster
*/

View File

@ -18,13 +18,15 @@
#define GROUP_H_
#include "PoolSQL.h"
#include "ObjectCollection.h"
#include "User.h"
using namespace std;
/**
* The Group class.
*/
class Group : public PoolObjectSQL
class Group : public PoolObjectSQL, ObjectCollection
{
public:
/**
@ -47,6 +49,25 @@ public:
*/
int from_xml(const string &xml_str);
/**
* Adds this object's ID to the set. The object MUST be a User, locked.
* The group's ID is added to the User's set.
* @param object The new object
*
* @return 0 on success, -1 if the ID was already in the set
*/
int add_collection_id(PoolObjectSQL* object);
/**
* Deletes this object's ID from the set. The object MUST be a User,
* locked. The group's ID is deleted form the User's set.
* @param object The object
*
* @return 0 on success, -1 if the ID was not in the set
*/
int del_collection_id(PoolObjectSQL* object);
private:
// -------------------------------------------------------------------------
@ -104,6 +125,13 @@ private:
* @return 0 on success
*/
int update(SqlDB *db);
// *************************************************************************
// ID Set management
// *************************************************************************
int add_del_collection_id(User* object, bool add);
};
#endif /*GROUP_H_*/

View File

@ -171,17 +171,6 @@ public:
return last_monitored;
};
/**
* Sets the cluster for this host
* @param cluster_id Cluster's oid
* @return 0 on success
*/
int set_cluster(int cluster_id)
{
gid = cluster_id;
return 0;
};
// ------------------------------------------------------------------------
// Share functions
// ------------------------------------------------------------------------
@ -293,6 +282,12 @@ public:
return host_share.test(cpu,mem,disk);
}
/**
* Adds the Host oid to the Cluster (gid), should be called after
* the constructor.
*/
int add_to_cluster();
private:
// -------------------------------------------------------------------------
@ -343,7 +338,7 @@ private:
// *************************************************************************
Host(int id=-1,
int cluster_id=-1,
int cluster_id=0,
const string& hostname="",
const string& im_mad_name="",
const string& vmm_mad_name="",
@ -351,6 +346,17 @@ private:
virtual ~Host();
/**
* Deletes the Host oid from the cluster it belongs to. Must be called
* before the Host is dropped.
*/
int delete_from_cluster();
/**
* Helper, adds or deletes this Host ID from its Cluster
*/
int add_del_to_cluster(bool add);
// *************************************************************************
// DataBase implementation (Private)
// *************************************************************************

View File

@ -165,6 +165,17 @@ public:
return PoolSQL::search(oids, Host::table, where);
};
/**
* Drops the object's data in the data base. The object mutex SHOULD be
* locked.
* @param objsql a pointer to the object
* @return 0 on success.
*/
int drop(Host * host)
{
host->delete_from_cluster();
return host->drop(db);
};
private:
/**

191
include/ObjectCollection.h Normal file
View File

@ -0,0 +1,191 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef OBJECT_COLLECTION_H_
#define OBJECT_COLLECTION_H_
#include <set>
using namespace std;
/**
* Class to store a set of PoolObjectSQL IDs.
*/
class ObjectCollection
{
public:
ObjectCollection(const string& _collection_name)
:collection_name(_collection_name)
{};
~ObjectCollection(){};
/**
* Adds this object's ID to the set.
* @param object The new object
*
* @return 0 on success, -1 if the ID was already in the set
*/
virtual int add_collection_id(PoolObjectSQL* object)
{
return add_collection_id(object->get_oid());
};
/**
* Deletes this object's ID from the set.
* @param object The object
*
* @return 0 on success, -1 if the ID was not in the set
*/
virtual int del_collection_id(PoolObjectSQL* object)
{
return del_collection_id(object->get_oid());
};
/**
* Returns how many IDs are there in the set.
* @return how many IDs are there in the set.
*/
int get_collection_size()
{
return collection_set.size();
};
protected:
/**
* Rebuilds the object from an xml node
* @param node The xml node pointer
*
* @return 0 on success, -1 otherwise
*/
int from_xml_node(const xmlNodePtr node)
{
ObjectXML xml(node);
int rc = 0;
int id;
vector<string> values;
vector<string>::iterator it;
istringstream iss;
string xpath_expr = "/" + collection_name + "/ID";
values = xml[xpath_expr.c_str()];
for ( it = values.begin() ; it < values.end(); it++ )
{
iss.str(*it);
iss >> dec >> id;
if ( iss.fail() )
{
rc = -1;
}
else
{
collection_set.insert(id);
}
}
return rc;
};
/**
* Function to print the Collection object into a string in
* XML format
* @param xml the resulting XML string
* @return a reference to the generated string
*/
string& to_xml(string& xml) const
{
ostringstream oss;
set<int>::iterator it;
oss << "<" << collection_name << ">";
for ( it = collection_set.begin(); it != collection_set.end(); it++ )
{
oss << "<ID>" << *it << "</ID>";
}
oss << "</" << collection_name << ">";
xml = oss.str();
return xml;
};
/**
* Adds an ID to the set.
* @param id The new id
*
* @return 0 on success, -1 if the ID was already in the set
*/
int add_collection_id(int id)
{
pair<set<int>::iterator,bool> ret;
ret = collection_set.insert(id);
if( !ret.second )
{
return -1;
}
return 0;
};
/**
* Deletes an ID from the set.
* @param id The id
*
* @return 0 on success, -1 if the ID was not in the set
*/
int del_collection_id(int id)
{
if( collection_set.erase(id) != 1 )
{
return -1;
}
return 0;
};
/**
* Returns a copy of the IDs set
*/
set<int> get_collection_copy()
{
return set<int> (collection_set);
};
private:
/**
* The collection's name
*/
string collection_name;
/**
* Set containing the relations IDs
*/
set<int> collection_set;
};
#endif /*OBJECT_COLLECTION_H_*/

View File

@ -69,10 +69,13 @@ public:
return uid;
};
// TODO: Check if uid == -1?
// What happens with user, is the user his owner, or uid = -1?
int set_uid(int _uid)
virtual int set_uid(int _uid)
{
if( uid == -1 )
{
return -1;
}
uid = _uid;
return 0;
}
@ -82,7 +85,7 @@ public:
return gid;
};
int set_gid(int _gid)
virtual int set_gid(int _gid)
{
if( gid == -1 )
{
@ -361,4 +364,4 @@ private:
static const char * error_attribute_name;
};
#endif /*POOL_OBJECT_SQL_H_*/
#endif /*POOL_OBJECT_SQL_H_*/

View File

@ -27,6 +27,8 @@
#include "VMTemplatePool.h"
#include "GroupPool.h"
#include "AuthManager.h"
#include <xmlrpc-c/base.hpp>
#include <xmlrpc-c/registry.hpp>
#include <xmlrpc-c/server_abyss.hpp>
@ -228,6 +230,12 @@ private:
return oss.str();
}
static string authorization_error (const string& method,
const string &action,AuthRequest::Object ob,int uid,int id)
{
return authorization_error(method,action,get_object_name(ob),uid,id);
}
/**
* Logs authenticate errors
* @param method name of the RM method where the error arose
@ -271,6 +279,11 @@ private:
return oss.str();
}
static string get_error (const string& method,AuthRequest::Object ob,int id)
{
return get_error(method,get_object_name(ob),id);
}
/**
* Logs action errors
* @param method name of the RM method where the error arose
@ -312,72 +325,157 @@ private:
return oss.str();
}
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// TODO: enum of Objects is maintained in AuthManager.h, could be moved
// to Nebula.h
enum Object
static string action_error (const string& method,const string &action,
AuthRequest::Object ob,int id,int rc)
{
VM,
HOST,
NET,
IMAGE,
USER,
CLUSTER,
TEMPLATE,
GROUP
};
return action_error(method, action, get_object_name(ob), id, rc);
}
PoolSQL * get_pool(Object ob)
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// Constants and Helpers
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
PoolSQL * get_pool(AuthRequest::Object ob)
{
switch (ob)
{
case VM: return static_cast<PoolSQL*>(vmpool);
case HOST: return static_cast<PoolSQL*>(hpool);
case NET: return static_cast<PoolSQL*>(vnpool);
case IMAGE: return static_cast<PoolSQL*>(ipool);
case USER: return static_cast<PoolSQL*>(upool);
case CLUSTER: return static_cast<PoolSQL*>(cpool);
case TEMPLATE: return static_cast<PoolSQL*>(tpool);
case GROUP: return static_cast<PoolSQL*>(gpool);
case AuthRequest::VM: return static_cast<PoolSQL*>(vmpool);
case AuthRequest::HOST: return static_cast<PoolSQL*>(hpool);
case AuthRequest::NET: return static_cast<PoolSQL*>(vnpool);
case AuthRequest::IMAGE: return static_cast<PoolSQL*>(ipool);
case AuthRequest::USER: return static_cast<PoolSQL*>(upool);
case AuthRequest::CLUSTER: return static_cast<PoolSQL*>(cpool);
case AuthRequest::TEMPLATE: return static_cast<PoolSQL*>(tpool);
case AuthRequest::GROUP: return static_cast<PoolSQL*>(gpool);
}
};
string get_method_prefix(Object ob)
static string get_method_prefix(AuthRequest::Object ob)
{
switch (ob)
{
case VM: return "VirtualMachine";
case HOST: return "Host";
case NET: return "VirtualNetwork";
case IMAGE: return "Image";
case USER: return "User";
case CLUSTER: return "Cluster";
case TEMPLATE: return "Template";
case GROUP: return "Group";
case AuthRequest::VM: return "VirtualMachine";
case AuthRequest::HOST: return "Host";
case AuthRequest::NET: return "VirtualNetwork";
case AuthRequest::IMAGE: return "Image";
case AuthRequest::USER: return "User";
case AuthRequest::CLUSTER: return "Cluster";
case AuthRequest::TEMPLATE: return "Template";
case AuthRequest::GROUP: return "Group";
}
};
string get_object_name(Object ob)
static string get_object_name(AuthRequest::Object ob)
{
switch (ob)
{
case VM: return "VM";
case HOST: return "HOST";
case NET: return "NET";
case IMAGE: return "IMAGE";
case USER: return "USER";
case CLUSTER: return "CLUSTER";
case TEMPLATE: return "TEMPLATE";
case GROUP: return "GROUP";
case AuthRequest::VM: return "VM";
case AuthRequest::HOST: return "HOST";
case AuthRequest::NET: return "NET";
case AuthRequest::IMAGE: return "IMAGE";
case AuthRequest::USER: return "USER";
case AuthRequest::CLUSTER: return "CLUSTER";
case AuthRequest::TEMPLATE: return "TEMPLATE";
case AuthRequest::GROUP: return "GROUP";
}
};
int add_object_group(
AuthRequest::Object object_type,
AuthRequest::Object group_type,
int object_id,
int group_id,
ostringstream& oss,
bool add=true)
{
int rc = 0;
PoolSQL * object_pool = get_pool(object_type);
PoolSQL * group_pool = get_pool(group_type);
string method_name = get_method_prefix(object_type) + "Add";
PoolObjectSQL * object = 0;
PoolObjectSQL * group = 0;
ObjectCollection * group_collection = 0;
// Get group locked
group = group_pool->get(group_id,true);
if ( group == 0 )
{
goto error_get_group;
}
// Get object locked
object = object_pool->get(object_id,true);
if ( object == 0 )
{
goto error_get_object;
}
// Add/Delete object to the group
group_collection = dynamic_cast<ObjectCollection*>(group);
if( group_collection == 0 )
{
goto error_group_add_del;
}
if(add)
{
rc = group_collection->add_collection_id(object);
}
else
{
rc = group_collection->del_collection_id(object);
}
if( rc != 0 )
{
goto error_group_add_del;
}
// Update the DB
group_pool->update(group);
object_pool->update(object);
object->unlock();
group->unlock();
return 0;
error_get_object:
oss.str(get_error(method_name, object_type, object_id));
goto error_common;
error_get_group:
oss.str(get_error(method_name, group_type, group_id));
goto error_common;
error_group_add_del:
oss.str(action_error(method_name, "MANAGE", group_type, group_id, rc));
goto error_common;
error_common:
if( object != 0 )
{
object->unlock();
}
if( group != 0 )
{
group->unlock();
}
return -1;
}
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// XML-RPC Methods
@ -388,11 +486,19 @@ private:
/* Generic Helpers */
/* ---------------------------------------------------------------------- */
/**
* This method takes three arguments: oid, uid and gid. It changes the
* owner and/or group id of a PoolSQLObject.
* If the arguments (owner or gid) are -1, the value is not updated.
*
* PoolSQLObjects created with an uid or gid of -1 won't update their
* values.
*/
class GenericChown: public xmlrpc_c::method
{
public:
GenericChown(RequestManager * _rm,
Object _ob):
GenericChown(RequestManager * _rm,
AuthRequest::Object _ob):
rm(_rm),
ob(_ob)
{
@ -408,7 +514,43 @@ private:
private:
RequestManager * rm;
Object ob;
AuthRequest::Object ob;
};
/**
* This method takes two arguments: object_id and group_id.
* It adds/removes the object_id to the group and, if the object has a
* collection of IDs (e.g. User objects), the group_id is added/removed
* to the object's set as well.
*/
class GenericAddDelGroup: public xmlrpc_c::method
{
public:
GenericAddDelGroup(
RequestManager * _rm,
AuthRequest::Object _object_type,
AuthRequest::Object _group_type,
bool _add = true):
rm(_rm),
object_type(_object_type),
group_type(_group_type),
add(_add)
{
_signature="A:sii";
_help="Adds the element to the group";
};
~GenericAddDelGroup(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
RequestManager * rm;
AuthRequest::Object object_type;
AuthRequest::Object group_type;
bool add;
};
/* ---------------------------------------------------------------------- */
@ -1385,7 +1527,10 @@ private:
class UserAllocate: public xmlrpc_c::method
{
public:
UserAllocate(UserPool * _upool):upool(_upool)
UserAllocate(UserPool * _upool,
RequestManager * _rm)
:upool(_upool),
rm(_rm)
{
_signature="A:sss";
_help="Creates a new user";
@ -1398,7 +1543,8 @@ private:
xmlrpc_c::value * const retvalP);
private:
UserPool * upool;
UserPool * upool;
RequestManager * rm;
};
/* ---------------------------------------------------------------------- */

View File

@ -18,6 +18,7 @@
#define USER_H_
#include "PoolSQL.h"
#include "ObjectCollection.h"
using namespace std;
@ -27,7 +28,7 @@ using namespace std;
/**
* The User class.
*/
class User : public PoolObjectSQL
class User : public PoolObjectSQL, public ObjectCollection
{
public:
@ -101,6 +102,11 @@ public:
*/
static string sha1_digest(const string& pass);
/**
* Sets the User's gid and add the User's oid to that group
*/
int set_gid(int _gid);
private:
// -------------------------------------------------------------------------
// Friends
@ -166,6 +172,23 @@ protected:
virtual ~User();
// *************************************************************************
// Group IDs set Management
// *************************************************************************
/**
* Adds the User oid to the Main Group (gid), should be called after
* the constructor.
*/
int add_to_group();
/**
* Deletes the User ID from all the groups it belongs to. Must be called
* before the User is dropped.
*/
int delete_from_groups();
// *************************************************************************
// DataBase implementation
// *************************************************************************

View File

@ -94,6 +94,7 @@ public:
*/
int drop(User * user)
{
user->delete_from_groups();
return PoolSQL::drop(user);
};

View File

@ -110,6 +110,9 @@ Commands:
* delete (Removes a group)
onegroup delete <id>
* chown (Changes the Group owner)
onegroup chown <id> <owner_id>
* list (Lists all the groups in the pool)
onegroup list
@ -164,6 +167,19 @@ when "delete"
end
end
when "chown"
check_parameters("chown", 2)
obj_id = get_group_id(ARGV[0])
new_uid = ARGV[1].to_i
obj = OpenNebula::Group.new_with_id(obj_id, get_one_client)
result = obj.chown( new_uid )
if is_successful?(result)
puts "Group owner changed" if ops[:verbose]
end
when "list"
if !ops[:xml]
uplist=UPShow.new

View File

@ -21,7 +21,7 @@
#include <sstream>
#include "Cluster.h"
#include "Nebula.h"
const char * Cluster::table = "cluster_pool";
@ -36,7 +36,9 @@ const char * Cluster::db_bootstrap = "CREATE TABLE IF NOT EXISTS cluster_pool ("
/* ************************************************************************ */
Cluster::Cluster(int id, const string& name)
:PoolObjectSQL(id,name,-1,-1,table){};
:PoolObjectSQL(id,name,-1,-1,table),
ObjectCollection("HOSTS")
{};
Cluster::~Cluster(){};
@ -150,11 +152,15 @@ ostream& operator<<(ostream& os, Cluster& cluster)
string& Cluster::to_xml(string& xml) const
{
ostringstream oss;
string collection_xml;
ObjectCollection::to_xml(collection_xml);
oss <<
"<CLUSTER>" <<
"<ID>" << oid << "</ID>" <<
"<NAME>" << name << "</NAME>" <<
collection_xml <<
"</CLUSTER>";
xml = oss.str();
@ -168,6 +174,7 @@ string& Cluster::to_xml(string& xml) const
int Cluster::from_xml(const string& xml)
{
int rc = 0;
vector<xmlNodePtr> content;
// Initialize the internal XML object
update_from_str(xml);
@ -176,6 +183,18 @@ int Cluster::from_xml(const string& xml)
rc += xpath(oid, "/CLUSTER/ID", -1);
rc += xpath(name,"/CLUSTER/NAME", "not_found");
// Get associated classes
ObjectXML::get_nodes("/CLUSTER/HOSTS", content);
if( content.size() < 1 )
{
return -1;
}
// Set of IDs
rc += ObjectCollection::from_xml_node(content[0]);
if (rc != 0)
{
return -1;
@ -183,3 +202,50 @@ int Cluster::from_xml(const string& xml)
return 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Cluster::set_default_cluster()
{
int rc = 0;
Nebula& nd = Nebula::instance();
HostPool * hpool = nd.get_hpool();
Host * host;
// Get a copy of the set, because the original will be modified deleting
// elements from it.
set<int> host_set;
set<int>::iterator it;
host_set = get_collection_copy();
if( hpool == 0 )
{
return -1;
}
for ( it = host_set.begin(); it != host_set.end(); it++ )
{
host = hpool->get( *it, true );
if( host == 0 )
{
rc = -1;
continue;
}
rc += host->set_gid(ClusterPool::DEFAULT_CLUSTER_ID);
// TODO: this add_to_cluster method locks Cluster objects, which
// may lead to deadlocks. Maybe this movement to the default cluster
// should be made in the RM
rc += host->add_to_cluster();
hpool->update(host);
host->unlock();
}
return rc;
}

View File

@ -104,13 +104,9 @@ int ClusterPool::drop(Cluster * cluster)
{
int rc;
Host* host;
vector<int> hids;
vector<int>::iterator hid_it;
Nebula& nd = Nebula::instance();
HostPool * hpool = nd.get_hpool();
int cluster_id = cluster->get_oid();
ostringstream where;
@ -125,29 +121,10 @@ int ClusterPool::drop(Cluster * cluster)
return -1;
}
rc = cluster->drop(db);
// Move the hosts assigned to the deleted cluster to the default one
if( rc == 0 )
{
hpool->search(hids, where.str());
cluster->set_default_cluster();
for ( hid_it=hids.begin() ; hid_it < hids.end(); hid_it++ )
{
host = hpool->get(*hid_it, true);
if ( host == 0 )
{
continue;
}
set_default_cluster(host);
hpool->update(host);
host->unlock();
}
}
rc = cluster->drop(db);
return rc;
}

View File

@ -22,7 +22,6 @@
#include "Group.h"
const char * Group::table = "group_pool";
const char * Group::db_names = "oid, name, body, uid";
@ -33,16 +32,17 @@ const char * Group::db_bootstrap = "CREATE TABLE IF NOT EXISTS group_pool ("
/* ************************************************************************ */
/* Group :: Constructor/Destructor */
/* Group :: Constructor/Destructor */
/* ************************************************************************ */
Group::Group(int id, int uid, const string& name):
PoolObjectSQL(id,name,uid,-1,table){};
PoolObjectSQL(id,name,uid,-1,table),
ObjectCollection("USERS"){};
Group::~Group(){};
/* ************************************************************************ */
/* Group :: Database Access Functions */
/* Group :: Database Access Functions */
/* ************************************************************************ */
/* ------------------------------------------------------------------------ */
@ -134,7 +134,7 @@ error_name:
}
/* ************************************************************************ */
/* Group :: Misc */
/* Group :: Misc */
/* ************************************************************************ */
ostream& operator<<(ostream& os, Group& group)
@ -152,12 +152,16 @@ ostream& operator<<(ostream& os, Group& group)
string& Group::to_xml(string& xml) const
{
ostringstream oss;
string collection_xml;
ObjectCollection::to_xml(collection_xml);
oss <<
"<GROUP>" <<
"<ID>" << oid << "</ID>" <<
"<UID>" << uid << "</UID>" <<
"<NAME>" << name << "</NAME>" <<
collection_xml <<
"</GROUP>";
xml = oss.str();
@ -171,6 +175,7 @@ string& Group::to_xml(string& xml) const
int Group::from_xml(const string& xml)
{
int rc = 0;
vector<xmlNodePtr> content;
// Initialize the internal XML object
update_from_str(xml);
@ -180,6 +185,17 @@ int Group::from_xml(const string& xml)
rc += xpath(uid, "/GROUP/UID", -1);
rc += xpath(name,"/GROUP/NAME", "not_found");
// Get associated classes
ObjectXML::get_nodes("/GROUP/USERS", content);
if( content.size() < 1 )
{
return -1;
}
// Set of IDs
rc += ObjectCollection::from_xml_node(content[0]);
if (rc != 0)
{
return -1;
@ -187,3 +203,64 @@ int Group::from_xml(const string& xml)
return 0;
}
/* ************************************************************************ */
/* Group :: User ID Set */
/* ************************************************************************ */
int Group::add_collection_id(PoolObjectSQL* object)
{
// TODO: make a dynamic cast and check if object is indeed a User ?
return add_del_collection_id( static_cast<User*>(object), true );
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Group::del_collection_id(PoolObjectSQL* object)
{
// TODO: make a dynamic cast and check if object is indeed a User ?
return add_del_collection_id( static_cast<User*>(object), false );
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Group::add_del_collection_id(User* object, bool add)
{
int rc = 0;
ObjectCollection * object_collection = 0;
// Get object id
int object_id = object->get_oid();
// Add/Remove object to the group
if(add)
{
rc = ObjectCollection::add_collection_id(object_id);
}
else
{
rc = ObjectCollection::del_collection_id(object_id);
}
if( rc != 0 )
{
return -1;
}
// Users can be in more than one group, it has to store the
// reverse relation
object_collection = static_cast<ObjectCollection*>(object);
if(add)
{
rc = object_collection->add_collection_id( this );
}
else
{
rc = object_collection->del_collection_id( this );
}
return rc;
}

View File

@ -124,6 +124,8 @@ error_common:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// TODO: add error string
int GroupPool::drop(Group * group)
{
int rc;
@ -137,6 +139,15 @@ int GroupPool::drop(Group * group)
return -1;
}
if( group->get_collection_size() > 0 )
{
ostringstream oss;
oss << "Group " << group->get_oid() << " is not empty.";
NebulaLog::log("GROUP",Log::ERROR, oss.str());
return -1;
}
rc = group->drop(db);
return rc;

View File

@ -22,6 +22,7 @@
#include "Host.h"
#include "NebulaLog.h"
#include "Nebula.h"
/* ************************************************************************ */
/* Host :: Constructor/Destructor */
@ -52,6 +53,57 @@ Host::~Host()
}
}
/* ************************************************************************** */
/* Host :: Cluster Management */
/* ************************************************************************** */
int Host::add_to_cluster()
{
return add_del_to_cluster(true);
}
int Host::delete_from_cluster()
{
return add_del_to_cluster(false);
}
int Host::add_del_to_cluster(bool add)
{
// Add this Host's ID to the Cluster
int rc = 0;
Nebula& nd = Nebula::instance();
ClusterPool * cpool = nd.get_cpool();
if( cpool == 0 )
{
return -1;
}
Cluster * cluster = cpool->get( get_gid(), true );
if( cluster == 0 )
{
return -1;
}
if( add )
{
rc = static_cast<ObjectCollection*>(cluster)->add_collection_id(this);
}
else
{
rc = static_cast<ObjectCollection*>(cluster)->del_collection_id(this);
}
if( rc == 0 )
{
cpool->update(cluster);
}
cluster->unlock();
return rc;
}
/* ************************************************************************ */
/* Host :: Database Access Functions */
/* ************************************************************************ */

View File

@ -185,6 +185,18 @@ int HostPool::allocate (
*oid = PoolSQL::allocate(host, error_str);
if( *oid != -1 )
{
// Add this Host's ID to its cluster
host = get(*oid, true);
host->add_to_cluster();
update( host );
host->unlock();
}
return *oid;

View File

@ -276,6 +276,8 @@ void Nebula::start()
vnpool = new VirtualNetworkPool(db,mac_prefix,size);
gpool = new GroupPool(db);
upool = new UserPool(db);
nebula_configuration->get("DEFAULT_IMAGE_TYPE", default_image_type);
@ -288,8 +290,6 @@ void Nebula::start()
cpool = new ClusterPool(db);
gpool = new GroupPool(db);
tpool = new VMTemplatePool(db);
}
catch (exception&)

View File

@ -25,6 +25,7 @@ module OpenNebula
:info => "group.info",
:allocate => "group.allocate",
:delete => "group.delete",
:chown => "group.chown"
}
# Creates a Group description with just its identifier
@ -74,6 +75,13 @@ module OpenNebula
super(GROUP_METHODS[:delete])
end
# Changes the owner/group
# uid:: _Integer_ the new owner id. Set to -1 to leave the current one
# [return] nil in case of success or an Error object
def chown(uid)
super(GROUP_METHODS[:chown], uid, -1)
end
# ---------------------------------------------------------------------
# Helpers to get information
# ---------------------------------------------------------------------

View File

@ -257,7 +257,7 @@ class Migrator < MigratorBase
########################################################################
@db.run "CREATE TABLE db_versioning (oid INTEGER PRIMARY KEY, version INTEGER, timestamp INTEGER, comment VARCHAR(256));"
@db.run "CREATE TABLE template_pool (oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, uid INTEGER, public INTEGER);"
@db.run "CREATE TABLE template_pool (oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, uid INTEGER, gid INTEGER, public INTEGER);"
# The group pool has two default ones
@db.run "CREATE TABLE group_pool (oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, uid INTEGER, UNIQUE(name));"

View File

@ -232,7 +232,7 @@ void RequestManager::register_xml_methods()
RequestManager::VirtualMachineInfo(vmpool,upool));
xmlrpc_c::methodPtr vm_chown(new
RequestManager::GenericChown(this,VM));
RequestManager::GenericChown(this,AuthRequest::VM));
xmlrpc_c::methodPtr vm_pool_info(new
RequestManager::VirtualMachinePoolInfo(vmpool,upool));
@ -256,7 +256,7 @@ void RequestManager::register_xml_methods()
RequestManager::TemplatePublish(tpool, upool));
xmlrpc_c::methodPtr template_chown(new
RequestManager::GenericChown(this,TEMPLATE));
RequestManager::GenericChown(this,AuthRequest::TEMPLATE));
xmlrpc_c::methodPtr template_pool_info(new
RequestManager::TemplatePoolInfo(tpool,upool));
@ -303,6 +303,9 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr group_delete(new
RequestManager::GroupDelete(upool,gpool));
xmlrpc_c::methodPtr group_chown(new
RequestManager::GenericChown(this,AuthRequest::GROUP));
xmlrpc_c::methodPtr grouppool_info(new
RequestManager::GroupPoolInfo(upool,gpool));
@ -328,10 +331,10 @@ void RequestManager::register_xml_methods()
RequestManager::VirtualNetworkRemoveLeases(vnpool, upool));
xmlrpc_c::methodPtr vn_chown(new
RequestManager::GenericChown(this,NET));
RequestManager::GenericChown(this,AuthRequest::NET));
xmlrpc_c::methodPtr user_allocate(new
RequestManager::UserAllocate(upool));
RequestManager::UserAllocate(upool,this));
xmlrpc_c::methodPtr user_delete(new
RequestManager::UserDelete(upool));
@ -343,7 +346,18 @@ void RequestManager::register_xml_methods()
RequestManager::UserChangePassword(upool));
xmlrpc_c::methodPtr user_chown(new
RequestManager::GenericChown(this,USER));
RequestManager::GenericChown(this,AuthRequest::USER));
xmlrpc_c::methodPtr user_addgroup(new
RequestManager::GenericAddDelGroup(this,
AuthRequest::USER,
AuthRequest::GROUP));
xmlrpc_c::methodPtr user_delgroup(new
RequestManager::GenericAddDelGroup(this,
AuthRequest::USER,
AuthRequest::GROUP,
false));
xmlrpc_c::methodPtr userpool_info(new
RequestManager::UserPoolInfo(upool));
@ -373,7 +387,7 @@ void RequestManager::register_xml_methods()
RequestManager::ImageEnable(ipool, upool));
xmlrpc_c::methodPtr image_chown(new
RequestManager::GenericChown(this,IMAGE));
RequestManager::GenericChown(this,AuthRequest::IMAGE));
xmlrpc_c::methodPtr imagepool_info(new
RequestManager::ImagePoolInfo(ipool, upool));
@ -426,6 +440,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.group.allocate", group_allocate);
RequestManagerRegistry.addMethod("one.group.info", group_info);
RequestManagerRegistry.addMethod("one.group.delete", group_delete);
RequestManagerRegistry.addMethod("one.group.chown", group_chown);
RequestManagerRegistry.addMethod("one.grouppool.info", grouppool_info);
@ -449,6 +464,8 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.user.info", user_info);
RequestManagerRegistry.addMethod("one.user.passwd", user_change_password);
RequestManagerRegistry.addMethod("one.user.chown", user_chown);
RequestManagerRegistry.addMethod("one.user.addgroup", user_addgroup);
RequestManagerRegistry.addMethod("one.user.delgroup", user_delgroup);
RequestManagerRegistry.addMethod("one.userpool.info", userpool_info);

View File

@ -0,0 +1,167 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "RequestManager.h"
#include "NebulaLog.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::GenericAddDelGroup::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
int object_id, object_owner;
int group_id, group_owner;
int uid, rc;
PoolSQL * object_pool = rm->get_pool(object_type);
PoolSQL * group_pool = rm->get_pool(group_type);
string method_name = rm->get_method_prefix(object_type) + "Add";
PoolObjectSQL * object = 0;
PoolObjectSQL * group = 0;
ostringstream oss;
/* -- RPC specific vars -- */
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
oss << method_name << " invoked";
NebulaLog::log("ReM",Log::DEBUG,oss);
oss.str("");
// Get the parameters
session = xmlrpc_c::value_string(paramList.getString(0));
object_id = xmlrpc_c::value_int (paramList.getInt(1));
group_id = xmlrpc_c::value_int (paramList.getInt(2));
// Authenticate the user
uid = rm->upool->authenticate(session);
if ( uid == -1 )
{
goto error_authenticate;
}
// Get object owner
object = object_pool->get(object_id,true);
if ( object == 0 )
{
goto error_get_object;
}
object_owner = object->get_uid();
object->unlock();
object = 0;
// Get group owner
group = group_pool->get(group_id,true);
if ( group == 0 )
{
goto error_get_group;
}
group_owner = group->get_uid();
group->unlock();
group = 0;
// Authorize the operation
if ( uid != 0 ) // rc == 0 means oneadmin
{
AuthRequest ar(uid);
ar.add_auth(object_type, object_id, AuthRequest::MANAGE, 0, false);
ar.add_auth(group_type, group_id, AuthRequest::MANAGE, 0, false);
if (UserPool::authorize(ar) == -1)
{
goto error_authorize;
}
}
// Add the object_id to the group and, if the object keeps a list of the
// groups it belongs to, the group_id to it.
rc = rm->add_object_group(object_type,group_type, object_id, group_id, oss);
if( rc != 0 )
{
goto error_add_object_group;
}
// All nice, return success to the client
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
// Copy arrayresult into retval mem space
arrayresult = new xmlrpc_c::value_array(arrayData);
*retval = *arrayresult;
delete arrayresult; // and get rid of the original
return;
error_authenticate:
oss.str(authenticate_error(method_name));
goto error_common;
error_get_object:
oss.str(get_error(method_name, object_type, object_id));
goto error_common;
error_get_group:
oss.str(get_error(method_name, group_type, group_id));
goto error_common;
error_authorize:
// TODO: get real error from UserPool::authorize
oss.str(authorization_error(method_name, "MANAGE", object_type, uid, object_id));
goto error_common;
error_add_object_group:
error_common:
if( object != 0 )
{
object->unlock();
}
if( group != 0 )
{
group->unlock();
}
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
NebulaLog::log("ReM",Log::ERROR,oss);
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -19,8 +19,6 @@
#include "NebulaLog.h"
#include "Nebula.h"
#include "AuthManager.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -30,11 +28,13 @@ void RequestManager::GenericChown::execute(
{
string session;
int uid, obj_owner;
int uid, obj_owner, group_owner;
int oid, ownid, gid;
int rc;
PoolObjectSQL * obj;
PoolObjectSQL * obj = 0;
User * user = 0;
Group * group = 0;
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
@ -56,8 +56,6 @@ void RequestManager::GenericChown::execute(
ownid = xmlrpc_c::value_int (paramList.getInt(2));
gid = xmlrpc_c::value_int (paramList.getInt(3));
// TODO: check destination owner and/or group exist
// First, we need to authenticate the user
uid = rm->upool->authenticate(session);
@ -77,27 +75,69 @@ void RequestManager::GenericChown::execute(
obj_owner = obj->get_uid();
obj->unlock();
obj = 0;
//Authorize the operation
if ( uid != 0 ) // uid == 0 means oneadmin
// Get destination group
if( gid > -1 )
{
goto error_authorize;
group = rm->gpool->get(gid, true);
if( group == 0 )
{
goto error_group_get;
}
group_owner = group->get_uid();
group->unlock();
group = 0;
}
// TODO use auth manager
/*
if ( uid != 0 ) // uid == 0 means oneadmin
{
AuthRequest ar(uid);
// ar.add_auth(..);
ar.add_auth(ob, // Object
oid, // Object id
AuthRequest::MANAGE, // Action
obj_owner, // Owner
false); // Public
if( ownid > -1 )
{
ar.add_auth(AuthRequest::USER, // Object
ownid, // Object id
AuthRequest::MANAGE, // Action
ownid, // Owner
false); // Public
}
if( gid > -1 )
{
ar.add_auth(AuthRequest::GROUP, // Object
gid, // Object id
AuthRequest::MANAGE, // Action
group_owner, // Owner
false); // Public
}
if (UserPool::authorize(ar) == -1)
{
goto error_authorize;
}
}
*/
// Check destination user exists
if( ownid > -1 )
{
user = rm->upool->get(ownid, true);
if( user == 0 )
{
goto error_user_get;
}
user->unlock();
}
// Get the object locked again
obj = pool->get(oid,true);
@ -149,15 +189,27 @@ error_get:
goto error_common;
error_authorize:
// TODO: delete development comment
oss << authorization_error(method_name, "MANAGE", obj_name, uid, oid) <<
" Development functionality, only oneamdin can perform chown.";
// TODO: get real error from UserPool::authorize
oss.str(authorization_error(method_name, "MANAGE", obj_name, uid, oid));
goto error_common;
error_user_get:
oss.str(get_error(method_name,
rm->get_object_name(AuthRequest::USER),
ownid));
goto error_common;
error_group_get:
oss.str(get_error(method_name,
rm->get_object_name(AuthRequest::GROUP),
gid));
goto error_common;
error_set_uid:
oss.str(action_error(method_name, "SET_UID", obj_name, oid, rc));
obj->unlock();
goto error_common;
error_set_gid:
@ -168,10 +220,24 @@ error_set_gid:
obj->set_uid(obj_owner);
}
obj->unlock();
goto error_common;
error_common:
if( obj != 0 )
{
obj->unlock();
}
if( group != 0 )
{
group->unlock();
}
if( user != 0 )
{
user->unlock();
}
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));

View File

@ -28,7 +28,7 @@ void RequestManager::ClusterAdd::execute(
{
string session;
int hid;
int hid, host_gid;
int clid;
int rc;
@ -88,8 +88,17 @@ void RequestManager::ClusterAdd::execute(
goto error_host_get;
}
// Get current host cluster
host_gid = host->get_gid();
// Set cluster
rc = host->set_cluster(cluster->get_oid());
rc = host->set_gid(cluster->get_oid());
// Add host ID to cluster
if( rc == 0 )
{
static_cast<ObjectCollection*>(cluster)->add_collection_id(host);
}
if ( rc != 0 )
{
@ -98,10 +107,25 @@ void RequestManager::ClusterAdd::execute(
// Update the DB
ClusterAdd::hpool->update(host);
ClusterAdd::cpool->update(cluster);
cluster->unlock();
// TODO: This lock-unlock order may cause deadlocks
// Now get the old cluster, and remove the Host Id from it
cluster = ClusterAdd::cpool->get(host_gid, true);
if( cluster != 0 )
{
cluster->del_collection_id(host);
ClusterAdd::cpool->update(cluster);
cluster->unlock();
}
host->unlock();
cluster->unlock();
// All nice, return success to the client
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS

View File

@ -26,14 +26,16 @@ void RequestManager::ClusterRemove::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
string session;
int hid;
int rc;
int hid, host_gid;
int clid;
int rc;
const string method_name = "ClusterRemove";
const string method_name = "ClusterRemove";
Host * host;
Host * host;
Cluster * cluster;
ostringstream oss;
@ -46,8 +48,9 @@ void RequestManager::ClusterRemove::execute(
// Get the parameters
session = xmlrpc_c::value_string(paramList.getString(0));
hid = xmlrpc_c::value_int (paramList.getInt(1));
clid = ClusterPool::DEFAULT_CLUSTER_ID;
// Only oneadmin can delete clusters
//Authenticate the user
rc = ClusterRemove::upool->authenticate(session);
if ( rc == -1 )
@ -59,8 +62,9 @@ void RequestManager::ClusterRemove::execute(
if ( rc != 0 ) // rc == 0 means oneadmin
{
AuthRequest ar(rc);
ar.add_auth(AuthRequest::HOST,hid,AuthRequest::MANAGE,0,false);
ar.add_auth(AuthRequest::CLUSTER,clid,AuthRequest::USE,0,false);
if (UserPool::authorize(ar) == -1)
{
@ -68,6 +72,14 @@ void RequestManager::ClusterRemove::execute(
}
}
// Check if cluster exists
cluster = ClusterRemove::cpool->get(clid,true);
if ( cluster == 0 )
{
goto error_cluster_get;
}
// Check if host exists
host = ClusterRemove::hpool->get(hid,true);
@ -76,19 +88,45 @@ void RequestManager::ClusterRemove::execute(
goto error_host_get;
}
// Remove host from cluster
rc = ClusterRemove::cpool->set_default_cluster(host);
// Get current host cluster
host_gid = host->get_gid();
// Set cluster
rc = host->set_gid(cluster->get_oid());
// Add host ID to cluster
if( rc == 0 )
{
static_cast<ObjectCollection*>(cluster)->add_collection_id(host);
}
if ( rc != 0 )
{
goto error_cluster_remove;
goto error_cluster_add;
}
// Update the DB
ClusterRemove::hpool->update(host);
ClusterRemove::cpool->update(cluster);
cluster->unlock();
// TODO: This lock-unlock order may cause deadlocks
// Now get the old cluster, and remove the Host Id from it
cluster = ClusterRemove::cpool->get(host_gid, true);
if( cluster != 0 )
{
cluster->del_collection_id(host);
ClusterRemove::cpool->update(cluster);
cluster->unlock();
}
host->unlock();
// All nice, return success to the client
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
@ -105,19 +143,26 @@ error_authenticate:
goto error_common;
error_authorize:
oss.str(authorization_error(method_name, "MANAGE", "HOST", rc, -1));
oss.str(authorization_error(method_name, "USE", "CLUSTER", rc, clid));
goto error_common;
error_host_get:
cluster->unlock();
oss.str(get_error(method_name, "HOST", hid));
goto error_common;
error_cluster_remove:
error_cluster_get:
oss.str(get_error(method_name, "CLUSTER", clid));
goto error_common;
error_cluster_add:
host->unlock();
oss.str(action_error(method_name, "MANAGE", "HOST", hid, rc));
cluster->unlock();
oss.str(action_error(method_name, "USE", "CLUSTER", clid, rc));
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));

View File

@ -76,7 +76,8 @@ void RequestManager::UserAllocate::execute(
}
// Now let's add the user
rc = UserAllocate::upool->allocate(&uid,username,password,true,GroupPool::USERS_ID,error_str);
rc = UserAllocate::upool->allocate(&uid,username,password,true,
GroupPool::USERS_ID,error_str);
if ( rc == -1 )
{

View File

@ -74,6 +74,7 @@ source_files=[
'RequestManagerTemplatePublish.cc',
'RequestManagerTemplatePoolInfo.cc',
'RequestManagerChown.cc',
'RequestManagerAddDelGroup.cc',
]
# Build library

View File

@ -25,17 +25,110 @@
#include <iomanip>
#include "User.h"
#include "Nebula.h"
#include "Group.h"
/* ************************************************************************** */
/* User :: Constructor/Destructor */
/* ************************************************************************** */
User::User(int id, string name, string pass, bool _enabled, int _gid):
PoolObjectSQL(id,name,-1,_gid,table), password(pass), enabled(_enabled)
{};
PoolObjectSQL(id,name,-1,_gid,table), ObjectCollection("GROUPS"),
password(pass), enabled(_enabled)
{};
User::~User(){};
/* ************************************************************************** */
/* User :: Group Set Management */
/* ************************************************************************** */
int User::add_to_group()
{
// Add this User's ID to the Main Group
int rc = 0;
Nebula& nd = Nebula::instance();
GroupPool * gpool = nd.get_gpool();
if( gpool == 0 )
{
return -1;
}
Group * group = gpool->get( get_gid(), true );
if( group == 0 )
{
return -1;
}
rc = group->add_collection_id(this);
if( rc == 0 )
{
gpool->update(group);
}
group->unlock();
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::set_gid(int _gid)
{
gid = _gid;
// The primary group is also kept in the Group Ids set.
// This method may return -1, because the Group could be a secondary group
// and be already in the set.
add_to_group();
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::delete_from_groups()
{
int rc = 0;
Nebula& nd = Nebula::instance();
GroupPool * gpool = nd.get_gpool();
Group * group;
// Get a copy of the set, because the original will be modified deleting
// elements from it.
set<int> group_set;
set<int>::iterator it;
group_set = get_collection_copy();
if( gpool == 0 )
{
return -1;
}
for ( it = group_set.begin(); it != group_set.end(); it++ )
{
group = gpool->get( *it, true );
if( group == 0 )
{
rc = -1;
continue;
}
rc += group->del_collection_id(this);
gpool->update(group);
group->unlock();
}
return rc;
}
/* ************************************************************************** */
/* User :: Database Access Functions */
/* ************************************************************************** */
@ -141,9 +234,12 @@ ostream& operator<<(ostream& os, User& user)
string& User::to_xml(string& xml) const
{
ostringstream oss;
string collection_xml;
int enabled_int = enabled?1:0;
ObjectCollection::to_xml(collection_xml);
oss <<
"<USER>"
"<ID>" << oid <<"</ID>" <<
@ -151,6 +247,7 @@ string& User::to_xml(string& xml) const
"<GID>" << gid <<"</GID>" <<
"<PASSWORD>" << password <<"</PASSWORD>" <<
"<ENABLED>" << enabled_int <<"</ENABLED>" <<
collection_xml <<
"</USER>";
xml = oss.str();
@ -165,6 +262,7 @@ int User::from_xml(const string& xml)
{
int rc = 0;
int int_enabled;
vector<xmlNodePtr> content;
// Initialize the internal XML object
update_from_str(xml);
@ -177,6 +275,18 @@ int User::from_xml(const string& xml)
enabled = int_enabled;
// Get associated classes
ObjectXML::get_nodes("/USER/GROUPS", content);
if( content.size() < 1 )
{
return -1;
}
// Set of IDs
rc += ObjectCollection::from_xml_node(content[0]);
if (rc != 0)
{
return -1;

View File

@ -121,8 +121,9 @@ int UserPool::allocate (
int gid,
string& error_str)
{
User * user;
ostringstream oss;
User * user;
ostringstream oss;
int rc;
if ( username.empty() )
{
@ -142,6 +143,23 @@ int UserPool::allocate (
// Insert the Object in the pool
*oid = PoolSQL::allocate(user, error_str);
if( *oid != -1 )
{
// Add this User's ID to his group
user = get(*oid, true);
rc = user->add_to_group();
if( rc != 0 )
{
goto error_group;
}
update( user );
user->unlock();
}
return *oid;
@ -151,6 +169,12 @@ error_name:
error_duplicated:
oss << "NAME is already taken by USER " << user->get_oid() << ".";
goto error_common;
error_group:
oss << "Error trying to add USER to group " << gid << ".";
drop( user );
user->unlock();
error_common:
*oid = -1;