Statistics
| Branch: | Tag: | Revision:

one / include / AclManager.h @ 621a1869

History | View | Annotate | Download (15.1 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems                */
3
/*                                                                            */
4
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
5
/* not use this file except in compliance with the License. You may obtain    */
6
/* a copy of the License at                                                   */
7
/*                                                                            */
8
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
9
/*                                                                            */
10
/* Unless required by applicable law or agreed to in writing, software        */
11
/* distributed under the License is distributed on an "AS IS" BASIS,          */
12
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
13
/* See the License for the specific language governing permissions and        */
14
/* limitations under the License.                                             */
15
/* -------------------------------------------------------------------------- */
16

    
17
#ifndef ACL_MANAGER_H_
18
#define ACL_MANAGER_H_
19

    
20
#include "AuthManager.h"
21
#include "AuthRequest.h"
22
#include "PoolObjectSQL.h"
23
#include "AclRule.h"
24

    
25
#include "SqlDB.h"
26

    
27
using namespace std;
28

    
29
class PoolObjectAuth;
30

    
31
extern "C" void * acl_action_loop(void *arg);
32

    
33
/**
34
 *  This class manages the ACL rules and the authorization engine
35
 */
36
class AclManager : public Callbackable, public ActionListener
37
{
38
public:
39

    
40
    /**
41
     *  @param _db pointer to the DB
42
     *  @param zone_id of the Zone
43
     *  @param is_federation_slave true is this oned is a federation slave. If
44
     *  it is true, it will reload periodically rules from the DB
45
     *  @param timer_period period to reload the rules
46
     */
47
    AclManager(SqlDB * _db, int zone_id, bool is_federation_slave, time_t timer);
48

    
49
    virtual ~AclManager();
50

    
51
    /**
52
     *  Loads the ACL rule set from the DB, and starts the refresh loop is
53
     *  refresh_cache is set
54
     *    @return 0 on success.
55
     */
56
    int start();
57

    
58
    void finalize();
59

    
60
    /* ---------------------------------------------------------------------- */
61
    /* Rule management                                                        */
62
    /* ---------------------------------------------------------------------- */
63

    
64
    /**
65
     *  Takes an authorization request and checks if any rule in the ACL
66
     *  authorizes the operation.
67
     *
68
     *    @param uid The user ID requesting to be authorized
69
     *    @param user_groups Set of group IDs that the user is part of
70
     *    @param obj_perms The object's permission attributes
71
     *    @param op The operation to be authorized
72
     *    @return true if the authorization is granted by any rule
73
     */
74
    const bool authorize(int                    uid,
75
                         const set<int>&        user_groups,
76
                         const PoolObjectAuth&  obj_perms,
77
                         AuthRequest::Operation op);
78

    
79
    /**
80
     *  Adds a new rule to the ACL rule set
81
     *
82
     *    @param user 64 bit ID and flags
83
     *    @param resource 64 bit ID and flags
84
     *    @param rights 64 bit flags
85
     *    @param zone 64 bit flags
86
     *    @param error_str Returns the error reason, if any
87
     *
88
     *    @return the oid assigned to the rule on success,
89
     *    -1 if the rule exists,
90
     *    -2 if the rule is malformed,
91
     *    -3 if the DB insert failed
92
     */
93
    virtual int add_rule(long long user,
94
                         long long resource,
95
                         long long rights,
96
                         long long zone,
97
                         string&   error_str);
98
    /**
99
     *  Deletes a rule from the ACL rule set
100
     *
101
     *    @param oid Rule id
102
     *    @param error_str Returns the error reason, if any
103
     *    @return 0 on success
104
     */
105
    virtual int del_rule(int oid, string& error_str);
106

    
107
    /**
108
     *  Deletes a new rule from the ACL rule set
109
     *
110
     *    @param user 64 bit ID and flags
111
     *    @param resource 64 bit ID and flags
112
     *    @param rights 64 bit flags
113
     *    @param zone 64 bit flags
114
     *
115
     *    @param error_str Returns the error reason, if any
116
     *    @return 0 on success
117
     */
118
    virtual int del_rule(long long user,
119
                         long long resource,
120
                         long long rights,
121
                         long long zone,
122
                         string&   error_str);
123

    
124
    /**
125
     * Deletes rules that apply to this user id
126
     *
127
     * @param uid The user id
128
     */
129
    void del_uid_rules(int uid);
130

    
131
    /**
132
     * Deletes rules that apply to this group id
133
     *
134
     * @param gid The group id
135
     */
136
    void del_gid_rules(int gid);
137

    
138
    /**
139
     * Deletes rules that apply to this cluster id
140
     *
141
     * @param cid The cluster id
142
     */
143
    void del_cid_rules(int cid);
144

    
145
    /**
146
     * Deletes rules that apply to this cluster id
147
     *
148
     * @param zid The zone id
149
     */
150
    void del_zid_rules(int zid);
151

    
152
    /**
153
     * Deletes all rules that apply to this resource
154
     *
155
     * @param oid Id of the deleted object
156
     * @param obj_type Object type
157
     */
158
    void del_resource_rules(int oid, PoolObjectSQL::ObjectType obj_type);
159

    
160
    /**
161
     * Searches what resources of type obj_type the ACL rules set allows
162
     * the given user to perform the operation.
163
     *
164
     *    @param uid The user ID
165
     *    @param user_groups Set of group IDs that the user is part of
166
     *    @param obj_type The object over which the search will be performed
167
     *    @param op The operation to be searched
168
     *    @param all True if the user can perform the operation over any object
169
     *    @param oids Set of object IDs over which the user can operate
170
     *    @param gids Set of object group IDs over which the user can operate
171
     *    @param cids Set of object cluster IDs over which the user can operate
172
     */
173
    void reverse_search(int                       uid,
174
                        const set<int>&           user_groups,
175
                        PoolObjectSQL::ObjectType obj_type,
176
                        AuthRequest::Operation    op,
177
                        bool                      disable_all_acl,
178
                        bool                      disable_cluster_acl,
179
                        bool                      disable_group_acl,
180
                        bool&                     all,
181
                        vector<int>&              oids,
182
                        vector<int>&              gids,
183
                        vector<int>&              cids);
184

    
185
    /* ---------------------------------------------------------------------- */
186
    /* DB management                                                          */
187
    /* ---------------------------------------------------------------------- */
188

    
189
    /**
190
     *  Bootstraps the database table(s) associated to the ACL Manager
191
     *    @return 0 on success
192
     */
193
    static int bootstrap(SqlDB * _db);
194

    
195
    /**
196
     *  Dumps the rule set in XML format.
197
     *    @param oss The output stream to dump the rule set contents
198
     *    @return 0 on success
199
     */
200
    virtual int dump(ostringstream& oss);
201

    
202
    // ----------------------------------------
203
    // Refresh loop thread
204
    // ----------------------------------------
205

    
206
    /**
207
     *  Gets the AclManager thread identification. The thread is only
208
     *  initialized if the refresh_cache flag is true.
209
     *    @return pthread_t for the manager thread (that in the action loop).
210
     */
211
    pthread_t get_thread_id() const
212
    {
213
        return acl_thread;
214
    };
215

    
216
protected:
217

    
218
    /**
219
     *  Constructor for derived ACL managers. Classes derived from this one
220
     *  will operate in a stand-alone fashion (i.e. no refresh of ACL rules
221
     *  from DB)
222
     */
223
    AclManager(int _zone_id)
224
        :zone_id(_zone_id), db(0),lastOID(0), is_federation_slave(false)
225
    {
226
       pthread_mutex_init(&mutex, 0);
227
    };
228

    
229
    // ----------------------------------------
230
    // ACL rules management
231
    // ----------------------------------------
232

    
233
    /**
234
     *  ACL rules. Each rule is indexed by its 'user' long long attibute,
235
     *  several rules can apply to the same user
236
     */
237
    multimap<long long, AclRule*> acl_rules;
238

    
239
    /**
240
     *  Rules indexed by oid. Stores the same rules as acl_rules
241
     */
242
    map<int, AclRule *> acl_rules_oids;
243

    
244
private:
245

    
246
    /**
247
     *  Gets all rules that apply to the user_req and, if any of them grants
248
     *  permission, returns true.
249
     *
250
     *    @param user_req user/group id and flags
251
     *    @param resource_oid_req 64 bit request, ob. type and individual oid
252
     *    @param resource_gid_req 64 bit request, ob. type and group id
253
     *    @param resource_cid_req 64 bit request, ob. type and cluster id
254
     *    @param resource_all_req 64 bit request, ob. type and all flag
255
     *    @param rights_req Requested rights
256
     *    @param individual_obj_type Mask with ob. type and individual flags
257
     *    @param group_obj_type Mask with ob. type and group flags
258
     *    @param cluster_obj_type Mask with ob. type and cluster flags
259
     *    @param rules ACL rules to match
260
     *
261
     *    @return true if any rule grants permission
262
     */
263
    bool match_rules(
264
            const long long                     &user_req,
265
            const long long                     &resource_oid_req,
266
            const long long                     &resource_gid_req,
267
            const set<long long>                &resource_cid_req,
268
            const long long                     &resource_all_req,
269
            const long long                     &rights_req,
270
            const long long                     &resource_oid_mask,
271
            const long long                     &resource_gid_mask,
272
            const long long                     &resource_cid_mask,
273
            const multimap<long long, AclRule*> &rules);
274

    
275
    /**
276
     *  Wrapper for match_rules. It will check if any rules in the temporary
277
     *  multimap or in the internal one grants permission.
278
     *
279
     *    @param user_req user/group id and flags
280
     *    @param resource_oid_req 64 bit request, ob. type and individual oid
281
     *    @param resource_gid_req 64 bit request, ob. type and group id
282
     *    @param resource_cid_req 64 bit request, ob. type and cluster id
283
     *    @param resource_all_req 64 bit request, ob. type and all flag
284
     *    @param rights_req Requested rights
285
     *    @param individual_obj_type Mask with ob. type and individual flags
286
     *    @param group_obj_type Mask with ob. type and group flags
287
     *    @param cluster_obj_type Mask with ob. type and cluster flags
288
     *    @param tmp_rules Temporary map group of ACL rules
289
     *
290
     *    @return true if any rule grants permission
291
     */
292
    bool match_rules_wrapper(
293
            const long long                     &user_req,
294
            const long long                     &resource_oid_req,
295
            const long long                     &resource_gid_req,
296
            const set<long long>                &resource_cid_req,
297
            const long long                     &resource_all_req,
298
            const long long                     &rights_req,
299
            const long long                     &individual_obj_type,
300
            const long long                     &group_obj_type,
301
            const long long                     &cluster_obj_type,
302
            const multimap<long long, AclRule*> &tmp_rules);
303

    
304
    /**
305
     * Deletes all rules that match the user mask
306
     *
307
     * @param user_req Mask to match
308
     */
309
    void del_user_matching_rules(long long user_req);
310

    
311
    /**
312
     * Deletes all rules that match the resource mask
313
     *
314
     *    @param resource_req 64 bit request, ob. type and group id
315
     *    @param resource_mask Mask with ob. type and group flags
316
     */
317
    void del_resource_matching_rules(
318
            long long resource_req,
319
            long long resource_mask);
320

    
321
    /**
322
     * Deletes all rules that match the zone mask
323
     *
324
     * @param zone_req Mask to match
325
     */
326
    void del_zone_matching_rules(long long zone_req);
327

    
328
    // ----------------------------------------
329
    // Local zone
330
    // ----------------------------------------
331

    
332
    int zone_id;
333

    
334
    // ----------------------------------------
335
    // Mutex synchronization
336
    // ----------------------------------------
337

    
338
    pthread_mutex_t mutex;
339

    
340
    /**
341
     *  Function to lock the manager
342
     */
343
    void lock()
344
    {
345
        pthread_mutex_lock(&mutex);
346
    };
347

    
348
    /**
349
     *  Function to unlock the manager
350
     */
351
    void unlock()
352
    {
353
        pthread_mutex_unlock(&mutex);
354
    };
355

    
356
    // ----------------------------------------
357
    // DataBase implementation variables
358
    // ----------------------------------------
359

    
360
    /**
361
     *  Pointer to the database.
362
     */
363
    SqlDB * db;
364

    
365
    /**
366
     *  Last object ID assigned to a rule.
367
     */
368
    int lastOID;
369

    
370
    /**
371
     *  Tablename for the ACL rules
372
     */
373
    static const char * table;
374

    
375
    static const char * db_names;
376

    
377
    static const char * db_bootstrap;
378

    
379
    /**
380
     *  Inserts the last oid into the pool_control table
381
     */
382
    void update_lastOID();
383

    
384
    /**
385
     *  Callback function to unmarshall the ACL rules
386
     *    @param num the number of columns read from the DB
387
     *    @param names the column names
388
     *    @param vaues the column values
389
     *    @return 0 on success
390
     */
391
    int select_cb(void *nil, int num, char **values, char **names);
392

    
393
    /**
394
     *  Reads the ACL rule set from the database.
395
     *    @param db pointer to the db
396
     *    @return 0 on success
397
     */
398
    int select();
399

    
400
    /**
401
     *  Inserts the ACL rule in the database.
402
     *    @param rule to insert
403
     *    @return 0 on success
404
     */
405
    int insert(AclRule * rule)
406
    {
407
        return insert(rule, db);
408
    };
409

    
410
    /**
411
     *  Inserts the ACL rule in the database.
412
     *    @param rule to insert
413
     *    @db db pointer
414
     *
415
     *    @return 0 on success
416
     */
417
    static int insert(AclRule * rule, SqlDB * db);
418

    
419
    /**
420
     *  Drops an ACL rule from the database
421
     *
422
     *    @param oid Rule id
423
     *    @return 0 on success
424
     */
425
    int drop(int oid);
426

    
427
    /**
428
     *  Callback to set the lastOID
429
     */
430
    int  init_cb(void *nil, int num, char **values, char **names);
431

    
432
    // ----------------------------------------
433
    // Refresh loop thread
434
    // ----------------------------------------
435

    
436
    /**
437
     * Flag to refresh the cache periodically
438
     */
439
    bool            is_federation_slave;
440

    
441
    /**
442
     *  Timer period for the cache refresh loop.
443
     */
444
    time_t          timer_period;
445

    
446
    /**
447
     *  Thread id for the ACL Manager
448
     */
449
    pthread_t       acl_thread;
450

    
451
    /**
452
     *  Action engine for the Manager
453
     */
454
    ActionManager   am;
455

    
456
    /**
457
     *  Function to execute the Manager action loop method within a new pthread
458
     *  (requires C linkage)
459
     */
460
    friend void * acl_action_loop(void *arg);
461

    
462
    /**
463
     *  The action function executed when an action is triggered.
464
     *    @param action the name of the action
465
     *    @param arg arguments for the action function
466
     */
467
    void do_action(
468
        const string &  action,
469
        void *          arg);
470
};
471

    
472
#endif /*ACL_MANAGER_H*/
473