Revision 4c8b82e2

View differences:

include/ImageTemplate.h
33 33

  
34 34
    ~ImageTemplate(){};
35 35

  
36
    /**
37
     *  Checks the template for RESTRICTED ATTRIBUTES
38
     *    @param rs_attr the first restricted attribute found if any
39
     *    @return true if a restricted attribute is found in the template
40
     */
41
    bool check(string& rs_attr)
42
    {
43
        return Template::check(rs_attr, restricted_attributes);
44
    };
45

  
46
    /**
47
     * Deletes all restricted attributes
48
     */
49
    void remove_restricted()
50
    {
51
        Template::remove_restricted(restricted_attributes);
52
    };
53

  
54
    /**
55
     * Deletes all the attributes, except the restricted ones
56
     */
57
    void remove_all_except_restricted()
58
    {
59
        Template::remove_all_except_restricted(restricted_attributes);
60
    };
61

  
62 36
    bool is_saving()
63 37
    {
64 38
        bool save_as_hot;
......
73 47
        replace("SAVE_AS_HOT", "YES");
74 48
    }
75 49

  
76
private:
77
    friend class ImagePool;
50
    // -------------------------------------------------------------------------
51
    // Restricted attributes interface implementation
52
    // -------------------------------------------------------------------------
53
    virtual void remove_restricted()
54
    {
55
        Template::remove_restricted(restricted);
56
    };
78 57

  
79
    static vector<string> restricted_attributes;
58
    virtual bool check_restricted(string& rs_attr, const Template& base)
59
    {
60
        return Template::check_restricted(rs_attr, base, restricted);
61
    }
80 62

  
81
    bool has_restricted()
63
    virtual bool check_restricted(string& rs_attr)
82 64
    {
83
        return restricted_attributes.size() > 0;
84
    };
65
        return Template::check_restricted(rs_attr, restricted);
66
    }
67

  
68
    static void parse_restricted(vector<const SingleAttribute *>& ra)
69
    {
70
        Template::parse_restricted(ra, restricted);
71
    }
85 72

  
73
private:
86 74
    /**
87
     * Stores the attributes as restricted, these attributes will be used in
88
     * ImageTemplate::check
89
     * @param rattrs Attributes to restrict
75
     *  Restricted attribute list for ImageTemplates
90 76
     */
91
    static void set_restricted_attributes(vector<const SingleAttribute *>& rattrs)
92
    {
93
        Template::set_restricted_attributes(rattrs, restricted_attributes);
94
    };
77
    static std::map<std::string, std::set<std::string> > restricted;
95 78
};
96 79

  
97 80
/* -------------------------------------------------------------------------- */
include/Template.h
19 19

  
20 20
#include <iostream>
21 21
#include <map>
22
#include <set>
22 23
#include <vector>
24
#include <string>
23 25

  
24 26
#include <libxml/tree.h>
25 27
#include <libxml/parser.h>
......
55 57
        separator    = t.separator;
56 58
        xml_root     = t.xml_root;
57 59

  
58
        attributes.clear();
59

  
60 60
        for (it = t.attributes.begin() ; it != t.attributes.end() ; it++)
61 61
        {
62 62
            attributes.insert(make_pair(it->first,(it->second)->clone()));
......
404 404
    /**
405 405
     *  Merges another Template, adding the new attributes and
406 406
     *  replacing the existing ones
407
     *
408 407
     *    @param from_tmpl the template to be merged
409 408
     */
410 409
     void merge(const Template * from_tmpl);
411 410

  
412
     /**
413
      * Deletes all restricted attributes
414
      */
415
     virtual void remove_restricted();
416

  
417
     /**
418
      * Deletes all the attributes, except the restricted ones
419
      */
420
     virtual void remove_all_except_restricted();
421

  
422
     /**
423
      *  @return true if the template defines one or more restricted attributes
424
      */
425
     virtual bool has_restricted();
426

  
427
     /**
428
      *  @return true if template is empty
429
      */
430
     bool empty()
431
     {
432
         return attributes.empty();
433
     }
411
    /**
412
     *  Check if the template can be safely merge with a base template. If a
413
     *  restricted attribute is found it is check that it has the same value in
414
     *  base.
415
     *    @param rs_attr the first restricted attribute found with a different
416
     *    value in base
417
     *    @param base template used to check restricted values.
418
     *
419
     *    @return true if a restricted attribute with a different value is found
420
     *    in the template
421
     *
422
     *   The version of this method without base template just look for any
423
     *   restricted attribute.
424
     */
425
    virtual bool check_restricted(string& rs_attr, const Template& base)
426
    {
427
        return false;
428
    }
429

  
430
    virtual bool check_restricted(string& rs_attr)
431
    {
432
        return false;
433
    }
434

  
435
    /**
436
     *  Removes a restricted attribute from the template. For vector attributes
437
     *  only restricted sub attributes are removed.
438
     */
439
    virtual void remove_restricted(){};
440

  
441
    /**
442
     *  @return true if template is empty
443
     */
444
    bool empty()
445
    {
446
        return attributes.empty();
447
    }
434 448

  
435 449
protected:
436 450
    /**
437 451
     *  The template attributes
438 452
     */
439
    multimap<string,Attribute *>    attributes;
453
    multimap<string,Attribute *> attributes;
440 454

  
441 455
    /**
442 456
     *  Builds a SingleAttribute from the given node
......
455 469
    Attribute* vector_xml_att(const xmlNode * node);
456 470

  
457 471
    /**
458
     * Stores the attributes as restricted, these attributes will be used in
459
     * Template::check
460
     * @param rattrs Attributes to restrict
461
     * @param restricted_attributes The attributes will be stored here
472
     *  Parses a list of restricted attributes in the form ATTRIBUTE_NAME or
473
     *  ATTRIBUTE_NAME/SUBATTRIBUTE.
474
     *    @param ras list of restricted attributes
475
     *    @param rattr_m result list of attributes indexed by ATTRIBUTE_NAME.
476
     *    RAs are stored:
477
     *      {
478
     *        RESTRICTED_ATTR_NAME => [ RESTRICTED_SUB_ATTRIBUTES ],
479
     *        ...
480
     *      }
481
     *    If the RA is Single the sub attribute list will be empty.
462 482
     */
463
    static void set_restricted_attributes(
464
            vector<const SingleAttribute *>& rattrs,
465
            vector<string>& restricted_attributes);
483
    static void parse_restricted(const vector<const SingleAttribute *>& ras,
484
        std::map<std::string, std::set<std::string> >& rattr_m);
466 485

  
467 486
    /**
468
     *  Checks the template for RESTRICTED ATTRIBUTES
469
     *    @param rs_attr the first restricted attribute found if any
470
     *    @return true if a restricted attribute is found in the template
487
     *  Removes a restricted attribute from the template. For vector attributes
488
     *  only restricted sub attributes are removed.
471 489
     */
472
    bool check(string& rs_attr, const vector<string> &restricted_attributes);
490
    void remove_restricted(
491
            const std::map<std::string, std::set<std::string> >& ras);
473 492

  
474 493
    /**
475
     * Deletes all restricted attributes
476
     */
477
    void remove_restricted(const vector<string> &restricted_attributes);
478

  
479
    /**
480
     * Deletes all the attributes, except the restricted ones
494
     *  Check if the template can be safely merge with a base template. If a
495
     *  restricted attribute is found it is check that it has the same value in
496
     *  base.
497
     *    @param rs_attr the first restricted attribute found with a different
498
     *    value in base
499
     *    @param base template used to check restricted values.
500
     *    @param ras list of restricted attributes.
501
     *
502
     *    @return true if a restricted attribute with a different value is found
503
     *    in the template
481 504
     */
482
    void remove_all_except_restricted(const vector<string> &restricted_attributes);
505
    bool check_restricted(string& rs_attr, const Template& base,
506
           const std::map<std::string, std::set<std::string> >& ras);
483 507

  
508
    bool check_restricted(string& rs_attr,
509
           const std::map<std::string, std::set<std::string> >& ras);
484 510
    /**
485 511
     * Updates the xml root element name
486 512
     *
include/VirtualMachineTemplate.h
29 29
class VirtualMachineTemplate : public Template
30 30
{
31 31
public:
32
    VirtualMachineTemplate():
33
        Template(false,'=',"TEMPLATE"){};
32
    VirtualMachineTemplate():Template(false,'=',"TEMPLATE"){};
34 33

  
35 34
    VirtualMachineTemplate(
36 35
            bool _replace_mode,
......
42 41

  
43 42
    VirtualMachineTemplate(VirtualMachineTemplate& vmt):Template(vmt){};
44 43

  
45
    /**
46
     *  Checks the template for RESTRICTED ATTRIBUTES
47
     *    @param rs_attr the first restricted attribute found if any
48
     *    @return true if a restricted attribute is found in the template
49
     */
50
    bool check(string& rs_attr)
51
    {
52
        return Template::check(rs_attr, restricted_attributes);
53
    };
54

  
55
    /**
56
     * Deletes all restricted attributes
57
     */
58
    void remove_restricted()
59
    {
60
        Template::remove_restricted(restricted_attributes);
61
    };
62

  
63
    /**
64
     * Deletes all the attributes, except the restricted ones
65
     */
66
    void remove_all_except_restricted()
67
    {
68
        Template::remove_all_except_restricted(restricted_attributes);
69
    };
70

  
71 44
    void set_xml_root(const char * _xml_root)
72 45
    {
73 46
        Template::set_xml_root(_xml_root);
......
85 58
        target_name, const string& target_uname, const string& new_name,
86 59
        const string& new_uname);
87 60

  
88
private:
61
    // -------------------------------------------------------------------------
62
    // Restricted attributes interface implementation
63
    // -------------------------------------------------------------------------
64
    virtual void remove_restricted()
65
    {
66
        Template::remove_restricted(restricted);
67
    };
89 68

  
90
    friend class VirtualMachinePool;
69
    virtual bool check_restricted(string& rs_attr, const Template& base)
70
    {
71
        return Template::check_restricted(rs_attr, base, restricted);
72
    }
91 73

  
92
    static vector<string> restricted_attributes;
74
    virtual bool check_restricted(string& rs_attr)
75
    {
76
        return Template::check_restricted(rs_attr, restricted);
77
    }
93 78

  
94
    bool has_restricted()
79
    static void parse_restricted(vector<const SingleAttribute *>& ra)
95 80
    {
96
        return restricted_attributes.size() > 0;
97
    };
81
        Template::parse_restricted(ra, restricted);
82
    }
98 83

  
84
private:
99 85
    /**
100
     * Stores the attributes as restricted, these attributes will be used in
101
     * VirtualMachineTemplate::check
102
     * @param rattrs Attributes to restrict
86
     *  Restricted attribute list for VirtualMachineTemplates
103 87
     */
104
    static void set_restricted_attributes(vector<const SingleAttribute *>& rattrs)
105
    {
106
        Template::set_restricted_attributes(rattrs, restricted_attributes);
107
    };
88
    static std::map<std::string, std::set<std::string> > restricted;
108 89
};
109 90

  
110 91
/* -------------------------------------------------------------------------- */
include/VirtualNetworkTemplate.h
27 27
class VirtualNetworkTemplate : public Template
28 28
{
29 29
public:
30
    VirtualNetworkTemplate():
31
        Template(false,'=',"TEMPLATE"){};
30
    VirtualNetworkTemplate():Template(false,'=',"TEMPLATE"){};
32 31

  
33 32
    ~VirtualNetworkTemplate(){};
34 33

  
35
    /**
36
     *  Checks the template for RESTRICTED ATTRIBUTES
37
     *    @param rs_attr the first restricted attribute found if any
38
     *    @return true if a restricted attribute is found in the template
39
     */
40
    bool check(string& rs_attr)
34
    // -------------------------------------------------------------------------
35
    // Restricted attributes interface implementation
36
    // -------------------------------------------------------------------------
37
    virtual void remove_restricted()
41 38
    {
42
        return Template::check(rs_attr, restricted_attributes);
39
        Template::remove_restricted(restricted);
43 40
    };
44 41

  
45
    /**
46
     * Deletes all restricted attributes
47
     */
48
    void remove_restricted()
42
    virtual bool check_restricted(string& rs_attr, const Template& base)
49 43
    {
50
        Template::remove_restricted(restricted_attributes);
51
    };
44
        return Template::check_restricted(rs_attr, base, restricted);
45
    }
52 46

  
53
    /**
54
     * Deletes all the attributes, except the restricted ones
55
     */
56
    void remove_all_except_restricted()
47
    virtual bool check_restricted(string& rs_attr)
57 48
    {
58
        Template::remove_all_except_restricted(restricted_attributes);
59
    };
49
        return Template::check_restricted(rs_attr, restricted);
50
    }
60 51

  
61
private:
62

  
63
    friend class VirtualNetworkPool;
64

  
65
    static vector<string> restricted_attributes;
66

  
67
    bool has_restricted()
52
    static void parse_restricted(vector<const SingleAttribute *>& ra)
68 53
    {
69
        return restricted_attributes.size() > 0;
70
    };
54
        Template::parse_restricted(ra, restricted);
55
    }
71 56

  
57
private:
72 58
    /**
73
     * Stores the attributes as restricted, these attributes will be used in
74
     * VirtualMachineTemplate::check
75
     * @param rattrs Attributes to restrict
59
     *  Restricted attribute list for VirtualNetworkTemplates
76 60
     */
77
    static void set_restricted_attributes(vector<const SingleAttribute *>& rattrs)
78
    {
79
        Template::set_restricted_attributes(rattrs, restricted_attributes);
80
    };
61
    static std::map<std::string, std::set<std::string> > restricted;
81 62
};
82 63

  
83 64
/* -------------------------------------------------------------------------- */
share/etc/oned.conf
929 929
VM_RESTRICTED_ATTR = "EMULATOR"
930 930
VM_RESTRICTED_ATTR = "RAW"
931 931
VM_RESTRICTED_ATTR = "USER_PRIORITY"
932
#VM_RESTRICTED_ATTR = "USER_INPUTS/CPU"
933
#VM_RESTRICTED_ATTR = "USER_INPUTS/MEMORY"
934
#VM_RESTRICTED_ATTR = "USER_INPUTS/VCPU"
935
#VM_RESTRICTED_ATTR = "TEMPLATE/VCENTER_VM_FOLDER"
932
VM_RESTRICTED_ATTR = "USER_INPUTS/CPU"
933
VM_RESTRICTED_ATTR = "USER_INPUTS/MEMORY"
934
VM_RESTRICTED_ATTR = "USER_INPUTS/VCPU"
935
VM_RESTRICTED_ATTR = "VCENTER_VM_FOLDER"
936 936

  
937 937
#VM_RESTRICTED_ATTR = "RANK"
938 938
#VM_RESTRICTED_ATTR = "SCHED_RANK"
......
940 940
#VM_RESTRICTED_ATTR = "SCHED_REQUIREMENTS"
941 941

  
942 942
IMAGE_RESTRICTED_ATTR = "SOURCE"
943
#IMAGE_RESTRICTED_ATTR = "TEMPLATE/VCENTER_IMPORTED"
943
IMAGE_RESTRICTED_ATTR = "VCENTER_IMPORTED"
944 944

  
945 945
#*******************************************************************************
946 946
# The following restricted attributes only apply to VNets that are a reservation.
src/image/ImagePool.cc
67 67
        _default_type = "OS";
68 68
    }
69 69

  
70
    ImageTemplate::set_restricted_attributes(restricted_attrs);
70
    ImageTemplate::parse_restricted(restricted_attrs);
71 71

  
72 72
    register_hooks(hook_mads, remotes_location);
73 73
}
src/image/ImageTemplate.cc
19 19
/* -------------------------------------------------------------------------- */
20 20
/* -------------------------------------------------------------------------- */
21 21

  
22
vector<string> ImageTemplate::restricted_attributes;
22
std::map<std::string, std::set<std::string> > ImageTemplate::restricted;
23 23

  
24 24
/* -------------------------------------------------------------------------- */
25 25
/* -------------------------------------------------------------------------- */
src/pool/PoolObjectSQL.cc
172 172
int PoolObjectSQL::replace_template(
173 173
        const string& tmpl_str, bool keep_restricted, string& error)
174 174
{
175
    string ra;
176

  
175 177
    Template * old_tmpl = 0;
176 178
    Template * new_tmpl = get_new_template();
177 179

  
......
189 191

  
190 192
    if (obj_template != 0)
191 193
    {
194
        if ( keep_restricted &&  new_tmpl->check_restricted(ra, obj_template) )
195
        {
196
            error = "Tried to change restricted attribute: " + ra;
197

  
198
            delete new_tmpl;
199
            return -1;
200
        }
201

  
192 202
        old_tmpl = new Template(*obj_template);
193 203
    }
194

  
195
    if (keep_restricted && new_tmpl->has_restricted())
204
    else if ( keep_restricted && new_tmpl->check_restricted(ra) )
196 205
    {
197
        new_tmpl->remove_restricted();
206
        error = "Tried to set restricted attribute: " + ra;
198 207

  
199
        if (obj_template != 0)
200
        {
201
            obj_template->remove_all_except_restricted();
202

  
203
            new_tmpl->merge(obj_template);
204
        }
208
        delete new_tmpl;
209
        return -1;
205 210
    }
206 211

  
207 212
    delete obj_template;
......
257 262

  
258 263
    if ( obj_template != 0 )
259 264
    {
260
        old_tmpl = new Template(*obj_template);
261

  
262 265
        obj_template->merge(new_tmpl);
263 266

  
264 267
        delete new_tmpl;
src/rm/RequestManagerAllocate.cc
87 87

  
88 88
    if ( att.uid != 0 && att.gid != GroupPool::ONEADMIN_ID )
89 89
    {
90
        if (ttmpl->check(aname))
90
        if (ttmpl->check_restricted(aname))
91 91
        {
92 92
            att.resp_msg = "VM Template includes a restricted attribute "+aname;
93 93
            failure_response(AUTHORIZATION, att);
......
513 513

  
514 514
        // ------------ Check template for restricted attributes  --------------
515 515

  
516
        if ( att.uid != UserPool::ONEADMIN_ID && att.gid != GroupPool::ONEADMIN_ID )
516
        if ( att.uid != UserPool::ONEADMIN_ID &&
517
                att.gid != GroupPool::ONEADMIN_ID )
517 518
        {
518
            if (tmpl->check(aname))
519
            if (tmpl->check_restricted(aname))
519 520
            {
520 521
                att.resp_msg = "Template includes a restricted attribute "+aname;
521 522
                failure_response(AUTHORIZATION, att);
......
528 529
        // ------------------ Check permissions and ACLs  ----------------------
529 530
        tmpl->to_xml(tmpl_str);
530 531

  
531
        ar.add_create_auth(att.uid, att.gid, auth_object, tmpl_str); // CREATE IMAGE
532
        ar.add_create_auth(att.uid, att.gid, auth_object, tmpl_str);
532 533

  
533 534
        ar.add_auth(AuthRequest::USE, ds_perms); // USE DATASTORE
534 535

  
......
649 650
    VirtualMachineTemplate * ttmpl = static_cast<VirtualMachineTemplate *>(tmpl);
650 651

  
651 652
    // ------------ Check template for restricted attributes -------------------
652
    if (ttmpl->check(aname))
653
    if (ttmpl->check_restricted(aname))
653 654
    {
654 655
        att.resp_msg = "VM Template includes a restricted attribute " + aname;
655 656

  
src/rm/RequestManagerVMTemplate.cc
274 274

  
275 275
	if (att.uid!=UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID)
276 276
	{
277
		if (uattrs.check(aname))
277
		if (uattrs.check_restricted(aname, tmpl))
278 278
		{
279 279
			att.resp_msg ="User Template includes a restricted attribute " + aname;
280 280

  
src/rm/RequestManagerVirtualMachine.cc
69 69
    {
70 70
        string t_xml;
71 71

  
72
        ar.add_create_auth(att.uid, att.gid, PoolObjectSQL::IMAGE, tmpl->to_xml(t_xml));
72
        ar.add_create_auth(att.uid, att.gid, PoolObjectSQL::IMAGE, 
73
                tmpl->to_xml(t_xml));
73 74
    }
74 75

  
75 76
    if ( vtmpl != 0 )
......
1835 1836
    {
1836 1837
        string aname;
1837 1838

  
1838
        if (tmpl.check(aname))
1839
        if (tmpl.check_restricted(aname))
1839 1840
        {
1840 1841
            att.resp_msg = "Template includes a restricted attribute " + aname;
1841 1842
            failure_response(AUTHORIZATION, att);
......
1910 1911
        case VirtualMachine::DONE:
1911 1912
        case VirtualMachine::SUSPENDED:
1912 1913
        case VirtualMachine::ACTIVE:
1913
            att.resp_msg="Resize action is not available for state "+vm->state_str();
1914
            att.resp_msg="Resize action is not available for state " +
1915
                vm->state_str();
1916

  
1914 1917
            failure_response(ACTION, att);
1915 1918

  
1916 1919
            vm->unlock();
......
2042 2045
        case VirtualMachine::DONE:
2043 2046
        case VirtualMachine::SUSPENDED:
2044 2047
        case VirtualMachine::ACTIVE:
2045
            att.resp_msg = "Resize action is not available for state " + vm->state_str();
2048
            att.resp_msg = "Resize action is not available for state " + 
2049
                vm->state_str();
2050

  
2046 2051
            failure_response(ACTION, att);
2047 2052

  
2048 2053
            vm->unlock();
......
2298 2303
    {
2299 2304
        string aname;
2300 2305

  
2301
        if (tmpl.check(aname))
2306
        if (tmpl.check_restricted(aname))
2302 2307
        {
2303 2308
            att.resp_msg = "NIC includes a restricted attribute " + aname;
2304 2309
            return AUTHORIZATION;
2305 2310
        }
2306 2311
    }
2307 2312

  
2308
    if (quota_authorization(&tmpl, Quotas::NETWORK, att_quota, att.resp_msg) == false)
2313
    if (quota_authorization(&tmpl, Quotas::NETWORK, att_quota,
2314
                att.resp_msg) == false)
2309 2315
    {
2310 2316
        return AUTHORIZATION;
2311 2317
    }
......
2892 2898
    {
2893 2899
        string aname;
2894 2900

  
2895
        if (tmpl.check(aname))
2901
        if (tmpl.check_restricted(aname))
2896 2902
        {
2897 2903
            att.resp_msg = "Template includes a restricted attribute " + aname;
2898 2904
            failure_response(AUTHORIZATION, att);
src/template/Template.cc
331 331
    attributes.erase(index.first,index.second);
332 332

  
333 333
    return j;
334

  
335 334
}
336 335

  
337 336
/* -------------------------------------------------------------------------- */
......
587 586
/* ------------------------------------------------------------------------ */
588 587
/* ------------------------------------------------------------------------ */
589 588

  
590
void Template::merge(const Template * from_tmpl)
591
{
592
    multimap<string,Attribute *>::const_iterator it;
593

  
594
    for (it = from_tmpl->attributes.begin(); it != from_tmpl->attributes.end(); ++it)
595
    {
596
        this->erase(it->first);
597
    }
598

  
599
    for (it = from_tmpl->attributes.begin(); it != from_tmpl->attributes.end(); ++it)
600
    {
601
        this->set(it->second->clone());
602
    }
603
}
604

  
605
/* ------------------------------------------------------------------------ */
606
/* ------------------------------------------------------------------------ */
607

  
608 589
void Template::rebuild_attributes(const xmlNode * root_element)
609 590
{
610 591
    xmlNode * cur_node = 0;
......
639 620
/* -------------------------------------------------------------------------- */
640 621
/* -------------------------------------------------------------------------- */
641 622

  
642
void Template::set_restricted_attributes(vector<const SingleAttribute *>& rattrs,
643
    vector<string>& restricted_attributes)
623
void Template::clear()
644 624
{
645
    for (unsigned int i = 0 ; i < rattrs.size() ; i++ )
625
    if (attributes.empty())
646 626
    {
647
        string va = rattrs[i]->value();
648
        restricted_attributes.push_back(one_util::toupper(va));
627
        return;
649 628
    }
629

  
630
    multimap<string,Attribute *>::iterator it;
631

  
632
    for ( it = attributes.begin(); it != attributes.end(); it++)
633
    {
634
        delete it->second;
635
    }
636

  
637
    attributes.clear();
650 638
}
651 639

  
640

  
641
/* -------------------------------------------------------------------------- */
642
/* -------------------------------------------------------------------------- */
643
/*   RESTRICTED ATTRIBUTES INTERFACE                                          */
652 644
/* -------------------------------------------------------------------------- */
653 645
/* -------------------------------------------------------------------------- */
654 646

  
655
static int get_attributes(
656
        multimap<string, Attribute *>& attributes,
657
        const string& name, vector<const Attribute*>& values)
647
void Template::merge(const Template * from)
658 648
{
659
    multimap<string, Attribute *>::const_iterator       i;
660
    pair<multimap<string, Attribute *>::const_iterator,
661
    multimap<string, Attribute *>::const_iterator>      index;
662
    int                                           j;
663

  
664
    index = attributes.equal_range(name);
649
    multimap<string, Attribute *>::const_iterator it, jt;
665 650

  
666
    for ( i = index.first,j=0 ; i != index.second ; i++,j++ )
651
    for (it = from->attributes.begin(); it != from->attributes.end(); ++it)
667 652
    {
668
        values.push_back(i->second);
653
        erase(it->first);
669 654
    }
670 655

  
671
    return j;
656
    for (it = from->attributes.begin(); it != from->attributes.end(); ++it)
657
    {
658
        set(it->second->clone());
659
    }
672 660
}
673 661

  
674
bool Template::check(string& rs_attr, const vector<string> &restricted_attributes)
662
/* ------------------------------------------------------------------------ */
663
/* ------------------------------------------------------------------------ */
664

  
665
void Template::parse_restricted(const vector<const SingleAttribute *>& ras,
666
        std::map<std::string, std::set<std::string> >& ras_m)
675 667
{
676
    size_t pos;
677
    string avector, vattr;
678
    vector<const Attribute *> values;
668
    vector<const SingleAttribute *>::const_iterator it;
679 669

  
680
    for (unsigned int i=0; i < restricted_attributes.size(); i++)
670
    for (it = ras.begin(); it != ras.end(); ++it)
681 671
    {
682
        pos = restricted_attributes[i].find("/");
672
        string va  = (*it)->value();
673
        size_t pos = va.find("/");
683 674

  
684 675
        if (pos != string::npos) //Vector Attribute
685 676
        {
686
            int num;
677
            string avector = va.substr(0,pos);
678
            string vattr   = va.substr(pos+1);
679

  
680
            map<std::string, std::set<string> >::iterator jt;
687 681

  
688
            avector = restricted_attributes[i].substr(0,pos);
689
            vattr   = restricted_attributes[i].substr(pos+1);
682
            jt = ras_m.find(avector);
690 683

  
691
            //Template contains the attr
692
            if ((num = get_attributes(attributes, avector, values)) > 0 )
684
            if ( jt == ras_m.end() )
693 685
            {
694
                const VectorAttribute * attr;
686
                std::set<std::string> aset;
695 687

  
696
                for (int j=0; j<num ; j++ )
697
                {
698
                    attr = dynamic_cast<const VectorAttribute *>(values[j]);
688
                aset.insert(vattr);
699 689

  
700
                    if (attr == 0)
701
                    {
702
                        continue;
703
                    }
704

  
705
                    if ( !attr->vector_value(vattr.c_str()).empty() )
706
                    {
707
                        rs_attr = restricted_attributes[i];
708
                        return true;
709
                    }
710
                }
690
                ras_m.insert(make_pair(avector, aset));
711 691
            }
712
        }
713
        else //Single Attribute
714
        {
715
            if (get_attributes(attributes, restricted_attributes[i], values) > 0)
692
            else
716 693
            {
717
                rs_attr = restricted_attributes[i];
718
                return true;
694
                jt->second.insert(vattr);
719 695
            }
720 696
        }
721
    }
697
        else
698
        {
699
            std::set<std::string> eset;
722 700

  
723
    return false;
701
            ras_m.insert(make_pair(va, eset));
702
        }
703
    }
724 704
}
725 705

  
726 706
/* -------------------------------------------------------------------------- */
727 707
/* -------------------------------------------------------------------------- */
728 708

  
729
void Template::remove_restricted()
730
{}
709
static void restricted_values(const string& vname, const set<string>& vsubs,
710
        const Template& tmpl, vector<string>& rstrings)
711
{
712
    string value;
731 713

  
732
/* -------------------------------------------------------------------------- */
733
/* -------------------------------------------------------------------------- */
714
    vector<const VectorAttribute *>::const_iterator va_it;
715
    vector<const VectorAttribute *> va;
734 716

  
735
void Template::remove_all_except_restricted()
736
{}
717
    tmpl.get(vname, va);
737 718

  
738
/* -------------------------------------------------------------------------- */
739
/* -------------------------------------------------------------------------- */
719
    for ( va_it = va.begin(); va_it != va.end() ; ++va_it )
720
    {
721
        for (set<string>::iterator jt = vsubs.begin(); jt != vsubs.end(); ++jt)
722
        {
723
            if ( (*va_it)->vector_value(*jt, value) == 0 )
724
            {
725
                rstrings.push_back(value);
726
            }
727
        }
728
    }
740 729

  
741
bool Template::has_restricted()
742
{
743
    return false;
730
    sort(rstrings.begin(), rstrings.end());
744 731
}
745 732

  
746
/* -------------------------------------------------------------------------- */
747
/* -------------------------------------------------------------------------- */
748

  
749
static int get_attributes(
750
        multimap<string, Attribute *>& attributes,
751
        const string& name, vector<Attribute*>& values)
733
bool Template::check_restricted(string& ra, const Template& base,
734
        const std::map<std::string, std::set<std::string> >& ras)
752 735
{
753
    multimap<string, Attribute *>::iterator       i;
754
    pair<multimap<string, Attribute *>::iterator,
755
    multimap<string, Attribute *>::iterator>      index;
756
    int                                           j;
736
    std::map<std::string, std::set<std::string> >::const_iterator rit;
757 737

  
758
    index = attributes.equal_range(name);
759

  
760
    for ( i = index.first,j=0 ; i != index.second ; i++,j++ )
738
    for ( rit = ras.begin(); rit != ras.end(); ++rit )
761 739
    {
762
        values.push_back(i->second);
740
        if (!(rit->second).empty())
741
        {
742
            vector<string> rvalues, rvalues_base;
743

  
744
            restricted_values(rit->first, rit->second, *this, rvalues);
745
            restricted_values(rit->first, rit->second, base, rvalues_base);
746

  
747
            if ( rvalues != rvalues_base )
748
            {
749
                ra = rit->first;
750
                return true;
751
            }
752
        }
753
        else
754
        {
755
            if ( get(rit->first, ra) )
756
            {
757
                string ra_b;
758

  
759
                base.get(rit->first, ra_b);
760

  
761
                if ( ra_b != ra )
762
                {
763
                    return true;
764
                }
765
            }
766
        }
763 767
    }
764 768

  
765
    return j;
769
    return false;
766 770
}
767 771

  
768
void Template::remove_restricted(const vector<string> &restricted_attributes)
772
/* -------------------------------------------------------------------------- */
773
/* -------------------------------------------------------------------------- */
774

  
775
bool Template::check_restricted(string& ra,
776
        const std::map<std::string, std::set<std::string> >& ras)
769 777
{
770
    size_t pos;
771
    string avector, vattr;
772
    vector<Attribute *> values;
778
    std::map<std::string, std::set<std::string> >::const_iterator rit;
773 779

  
774
    for (unsigned int i=0; i < restricted_attributes.size(); i++)
780
    for ( rit = ras.begin(); rit != ras.end(); ++rit )
775 781
    {
776
        pos = restricted_attributes[i].find("/");
782
        const std::set<std::string>& sub = rit->second;
777 783

  
778
        if (pos != string::npos) //Vector Attribute
784
        if (!sub.empty()) //Vector Attribute
779 785
        {
780
            int num;
786
            // -----------------------------------------------------------------
787
            // -----------------------------------------------------------------
788
            std::set<std::string>::iterator jt;
789
            std::vector<VectorAttribute *>::iterator va_it;
781 790

  
782
            avector = restricted_attributes[i].substr(0,pos);
783
            vattr   = restricted_attributes[i].substr(pos+1);
791
            std::vector<VectorAttribute *> va;
784 792

  
785
            //Template contains the attr
786
            if ((num = get_attributes(attributes, avector,values)) > 0 )
787
            {
788
                VectorAttribute * attr;
793
            get(rit->first, va);
789 794

  
790
                for (int j=0; j<num ; j++ )
795
            for ( va_it = va.begin(); va_it != va.end() ; ++va_it )
796
            {
797
                for ( jt = sub.begin(); jt != sub.end(); ++jt )
791 798
                {
792
                    attr = dynamic_cast<VectorAttribute *>(values[j]);
793

  
794
                    if (attr == 0)
799
                    if ( (*va_it)->vector_value(*jt, ra) == 0 )
795 800
                    {
796
                        continue;
801
                        return true;
797 802
                    }
798

  
799
                    attr->remove(vattr);
800 803
                }
801 804
            }
802 805
        }
803
        else //Single Attribute
806
        else if ( get(rit->first, ra) ) //Single Attribute
804 807
        {
805
            erase(restricted_attributes[i]);
808
            return true;
806 809
        }
807 810
    }
811

  
812
    return false;
808 813
}
809 814

  
810 815
/* -------------------------------------------------------------------------- */
811 816
/* -------------------------------------------------------------------------- */
812 817

  
813
void Template::remove_all_except_restricted(const vector<string> &restricted_attributes)
818
void Template::remove_restricted(
819
        const std::map<std::string, std::set<std::string> >& ras)
814 820
{
815
    size_t pos;
816
    string avector, vattr;
817
    vector<Attribute *> values;
821
    std::map<std::string, std::set<std::string> >::const_iterator rit;
818 822

  
819
    vector<Attribute *> restricted;
820

  
821
    for (unsigned int i=0; i < restricted_attributes.size(); i++)
823
    for (rit=ras.begin(); rit!=ras.end(); ++rit)
822 824
    {
823
        pos = restricted_attributes[i].find("/");
824

  
825
        if (pos != string::npos) //Vector Attribute
825
        if (!(rit->second).empty()) //Vector Attribute
826 826
        {
827
            int num;
827
            std::set<std::string>::iterator jt;
828
            std::vector<VectorAttribute *>::iterator vat;
828 829

  
829
            avector = restricted_attributes[i].substr(0,pos);
830
            vattr   = restricted_attributes[i].substr(pos+1);
830
            std::vector<VectorAttribute *> va;
831 831

  
832
            //Template contains the attr
833
            if ((num = get_attributes(attributes, avector,values)) > 0 )
834
            {
835
                VectorAttribute * attr;
832
            get(rit->first, va);
836 833

  
837
                for (int j=0; j<num ; j++ )
834
            for (vat = va.begin(); vat != va.end() ; ++vat)
835
            {
836
                for (jt=(rit->second).begin(); jt != (rit->second).end(); ++jt)
838 837
                {
839
                    attr = dynamic_cast<VectorAttribute *>(values[j]);
840

  
841
                    if (attr == 0)
842
                    {
843
                        continue;
844
                    }
845

  
846
                    if ( !attr->vector_value(vattr.c_str()).empty() )
847
                    {
848
                        restricted.push_back(attr);
849
                    }
838
                    (*vat)->remove(*jt);
850 839
                }
851 840
            }
852 841
        }
853
        else //Single Attribute
842
        else
854 843
        {
855
            get_attributes(attributes, restricted_attributes[i], restricted);
844
            erase(rit->first);
856 845
        }
857 846
    }
847
}
858 848

  
859
    vector<Attribute *>::iterator res_it;
849
/*
850
ostringstream& Template::print_restricted(
851
        std::map<std::string, std::set<std::string> >& rattr_m,
852
        ostringstream &oss)
853
{
854
    std::map<std::string, std::set<std::string> >::iterator rit;
860 855

  
861
    for (res_it = restricted.begin(); res_it != restricted.end(); res_it++)
856
    for (rit=rmap.begin(); rit!=rmap.end(); ++rit)
862 857
    {
863
        remove(*res_it);
864
    }
858
        oss << std::endl << rit->first << std::endl;
865 859

  
866
    clear();
860
        std::set<std::string>::iterator jt;
867 861

  
868
    for (res_it = restricted.begin(); res_it != restricted.end(); res_it++)
869
    {
870
        set(*res_it);
862
        for ( jt=(rit->second).begin(); jt != (rit->second).end(); ++jt )
863
        {
864
            oss << "\t" << *jt << std::endl;
865
        }
871 866
    }
867

  
868
    return oss;
872 869
}
873 870

  
874
/* -------------------------------------------------------------------------- */
875
/* -------------------------------------------------------------------------- */
876 871

  
877
void Template::clear()
872
bool Template::remove_non_restricted(
873
        const std::map<std::string, std::set<std::string> >& ras)
878 874
{
879
    if (attributes.empty())
880
    {
881
        return;
882
    }
883

  
884
    multimap<string,Attribute *>::iterator it;
875
    multimap<string, Attribute *>::iterator it;
885 876

  
886
    for ( it = attributes.begin(); it != attributes.end(); it++)
877
    for (it = attributes.begin() ; it != attributes.end() ; )
887 878
    {
888
        delete it->second;
879
        if ( ras.find(it->first) != ras.end() )
880
        {
881
            delete it->second;
882

  
883
            it = attributes.erase(it);
884
        }
885
        else
886
        {
887
            ++it;
888
        }
889 889
    }
890 890

  
891
    attributes.clear();
891
    //Change to void
892
    return true;
892 893
}
894
*/
893 895

  
src/vm/VirtualMachine.cc
2223 2223
        bool            keep_restricted,
2224 2224
        string&         error)
2225 2225
{
2226
    string ra;
2227

  
2226 2228
    VirtualMachineTemplate * new_tmpl =
2227 2229
            new VirtualMachineTemplate(false,'=',"USER_TEMPLATE");
2228 2230

  
......
2238 2240
        return -1;
2239 2241
    }
2240 2242

  
2241
    if (keep_restricted)
2243
    if (user_obj_template != 0)
2242 2244
    {
2243
        new_tmpl->remove_restricted();
2244

  
2245
        if (user_obj_template != 0)
2245
        if (keep_restricted && new_tmpl->check_restricted(ra, user_obj_template))
2246 2246
        {
2247
            user_obj_template->remove_all_except_restricted();
2247
            error = "Tried to change restricted attribute: " + ra;
2248 2248

  
2249
            new_tmpl->merge(user_obj_template);
2249
            delete new_tmpl;
2250
            return -1;
2250 2251
        }
2251 2252
    }
2253
    else if (keep_restricted && new_tmpl->check_restricted(ra))
2254
    {
2255
        error = "Tried to set restricted attribute: " + ra;
2256

  
2257
        delete new_tmpl;
2258
        return -1;
2259
    }
2252 2260

  
2253 2261
    delete user_obj_template;
2254 2262

  
src/vm/VirtualMachinePool.cc
207 207
    }
208 208

  
209 209
    // Set restricted attributes
210
    VirtualMachineTemplate::set_restricted_attributes(restricted_attrs);
210
    VirtualMachineTemplate::parse_restricted(restricted_attrs);
211 211
}
212 212

  
213 213
/* -------------------------------------------------------------------------- */
src/vm/VirtualMachineTemplate.cc
19 19
/* -------------------------------------------------------------------------- */
20 20
/* -------------------------------------------------------------------------- */
21 21

  
22
vector<string> VirtualMachineTemplate::restricted_attributes;
22
std::map<std::string, std::set<std::string> > VirtualMachineTemplate::restricted;
23 23

  
24 24
/* -------------------------------------------------------------------------- */
25 25
/* -------------------------------------------------------------------------- */
src/vnm/VirtualNetworkPool.cc
90 90
    _mac_prefix <<= 8;
91 91
    _mac_prefix += tmp;
92 92

  
93
    VirtualNetworkTemplate::set_restricted_attributes(restricted_attrs);
93
    VirtualNetworkTemplate::parse_restricted(restricted_attrs);
94

  
94 95
    AddressRange::set_restricted_attributes(restricted_attrs);
95 96

  
96 97
    register_hooks(hook_mads, remotes_location);
src/vnm/VirtualNetworkTemplate.cc
19 19
/* -------------------------------------------------------------------------- */
20 20
/* -------------------------------------------------------------------------- */
21 21

  
22
vector<string> VirtualNetworkTemplate::restricted_attributes;
22
std::map<std::string, std::set<std::string> > VirtualNetworkTemplate::restricted;
23 23

  
24 24
/* -------------------------------------------------------------------------- */
25 25
/* -------------------------------------------------------------------------- */

Also available in: Unified diff