Statistics
| Branch: | Tag: | Revision:

one / include / AuthManager.h @ bfaabf35

History | View | Annotate | Download (13 KB)

1
/* -------------------------------------------------------------------------- */
2
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)             */
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 AUTH_MANAGER_H_
18
#define AUTH_MANAGER_H_
19

    
20
#include <time.h>
21

    
22
#include "MadManager.h"
23
#include "ActionManager.h"
24

    
25
#include "AuthManagerDriver.h"
26

    
27
using namespace std;
28

    
29
//Forward definition of the AuthRequest
30
class AuthRequest;
31

    
32
/* -------------------------------------------------------------------------- */
33
/* -------------------------------------------------------------------------- */
34

    
35
extern "C" void * authm_action_loop(void *arg);
36

    
37
class AuthManager : public MadManager, public ActionListener
38
{
39
public:
40

    
41
    AuthManager(
42
        time_t                      timer,
43
        time_t                      __time_out,
44
        vector<const Attribute*>&   _mads):
45
            MadManager(_mads), timer_period(timer)
46
    {
47
        _time_out = __time_out;
48

    
49
        am.addListener(this);
50

    
51
        pthread_mutex_init(&mutex,0);
52
    };
53

    
54
    ~AuthManager(){};
55

    
56
    enum Actions
57
    {
58
        AUTHENTICATE,
59
        AUTHORIZE,
60
        FINALIZE
61
    };
62

    
63
    /**
64
     *  Triggers specific actions to the Auth Manager. This function
65
     *  wraps the ActionManager trigger function.
66
     *    @param action the Auth Manager action
67
     *    @param request an auth request
68
     */
69
    void trigger(
70
        Actions       action,
71
        AuthRequest * request);
72

    
73
    /**
74
     *  This functions starts the associated listener thread, and creates a
75
     *  new thread for the AuthManager. This thread will wait in
76
     *  an action loop till it receives ACTION_FINALIZE.
77
     *    @return 0 on success.
78
     */
79
    int start();
80

    
81
    /**
82
     *  Loads Virtual Machine Manager Mads defined in configuration file
83
     *   @param uid of the user executing the driver. When uid is 0 the nebula
84
     *   identity will be used. Otherwise the Mad will be loaded through the
85
     *   sudo application.
86
     */
87
    void load_mads(int uid);
88

    
89
    /**
90
     *  Gets the thread identification.
91
     *    @return pthread_t for the manager thread (that in the action loop).
92
     */
93
    pthread_t get_thread_id() const
94
    {
95
        return authm_thread;
96
    };
97

    
98
    /**
99
     *  Notify the result of an auth request
100
     */
101
    void notify_request(int auth_id, bool result, const string& message);
102

    
103
    /**
104
     *  Discards a pending request. Call this before freeing not notified or
105
     *  timeout requests.
106
     */
107
    void discard_request(int auth_id)
108
    {
109
        lock();
110

    
111
        auth_requests.erase(auth_id);
112

    
113
        unlock();
114
    }
115

    
116
    /**
117
     *  Gets default timeout for Auth requests
118
     */
119
    static time_t  time_out()
120
    {
121
        return _time_out;
122
    }
123

    
124
private:
125
    /**
126
     *  Thread id for the Transfer Manager
127
     */
128
    pthread_t               authm_thread;
129

    
130
    /**
131
     *  Action engine for the Manager
132
     */
133
    ActionManager           am;
134

    
135
    /**
136
     *  List of pending requests
137
     */
138
    map<int, AuthRequest *> auth_requests;
139

    
140
    /**
141
     *  Mutex to access the auth_requests
142
     */
143
    pthread_mutex_t         mutex;
144

    
145
    /**
146
     *  Default timeout for Auth requests
147
     */
148
    static time_t           _time_out;
149

    
150
    /**
151
     *  Timer for the Manager (periocally triggers timer action)
152
     */
153
    time_t                  timer_period;
154

    
155
    /**
156
     *  Generic name for the Auth driver
157
     */
158
     static const char *  auth_driver_name;
159

    
160
    /**
161
     *  Returns a pointer to a Auth Manager driver.
162
     *    @param name of an attribute of the driver (e.g. its type)
163
     *    @param value of the attribute
164
     *    @return the Auth driver with attribute name equal to value
165
     *    or 0 in not found
166
     */
167
    const AuthManagerDriver * get(
168
        const string&   name,
169
        const string&   value)
170
    {
171
        return static_cast<const AuthManagerDriver *>
172
               (MadManager::get(0,name,value));
173
    };
174

    
175
    /**
176
     *  Returns a pointer to a Auth Manager driver. The driver is
177
     *  searched by its name.
178
     *    @param name the name of the driver
179
     *    @return the TM driver owned by uid with attribute name equal to value
180
     *    or 0 in not found
181
     */
182
    const AuthManagerDriver * get()
183
    {
184
        string name("NAME");
185

    
186
        return static_cast<const AuthManagerDriver *>
187
               (MadManager::get(0,name,auth_driver_name));
188
    };
189

    
190
    /**
191
     *  Function to execute the Manager action loop method within a new pthread
192
     * (requires C linkage)
193
     */
194
    friend void * authm_action_loop(void *arg);
195

    
196
    /**
197
     *  The action function executed when an action is triggered.
198
     *    @param action the name of the action
199
     *    @param arg arguments for the action function
200
     */
201
    void do_action(
202
        const string &  action,
203
        void *          arg);
204

    
205
    /**
206
     *  This function authenticates a user
207
     */
208
    void authenticate_action(AuthRequest * ar);
209

    
210
    /**
211
     *  This function authorizes a user request
212
     */
213
    void authorize_action(AuthRequest * ar);
214

    
215
    /**
216
     *  This function is periodically executed to check time_outs on requests
217
     */
218
    void timer_action();
219

    
220
    /**
221
     *  Function to lock the pool
222
     */
223
    void lock()
224
    {
225
        pthread_mutex_lock(&mutex);
226
    };
227

    
228
    /**
229
     *  Function to unlock the pool
230
     */
231
    void unlock()
232
    {
233
        pthread_mutex_unlock(&mutex);
234
    };
235

    
236
    /**
237
     *  Add a new request to the Request map
238
     *    @param ar pointer to the AuthRequest
239
     *    @return the id for the request
240
     */
241
    int add_request(AuthRequest *ar);
242

    
243
    /**
244
     *  Gets request from the Request map
245
     *    @param id for the request
246
     *    @return pointer to the AuthRequest
247
     */
248
    AuthRequest * get_request(int id);
249
};
250

    
251
/* -------------------------------------------------------------------------- */
252
/* -------------------------------------------------------------------------- */
253

    
254
/**
255
 *  The AuthRequest class is used to pass an Authorization or Authentication
256
 *  request to the AuthManager. The result of the request will be stored
257
 *  in the result and message attributes of this class.
258
 */
259
class AuthRequest : public ActionListener
260
{
261
public:
262
    AuthRequest(int _uid):
263
        result(false),
264
        timeout(false),
265
        uid(_uid),
266
        time_out(0),
267
        self_authorize(true)
268
    {
269
        am.addListener(this);
270
    };
271

    
272
    ~AuthRequest(){};
273

    
274
    /**
275
     *  Authorization Request Type
276
     */
277
    enum Operation
278
    {
279
        CREATE        = 0x1LL,  /**< Auth. to create an object                */
280
        DELETE        = 0x2LL,  /**< Auth. to delete an object                */
281
        USE           = 0x4LL,  /**< Auth. to use an object                   */
282
        MANAGE        = 0x8LL,  /**< Auth. to manage an object                */
283
        INFO          = 0x10LL, /**< Auth. to view an object                  */
284
        INFO_POOL     = 0x20LL, /**< Auth. to view any object in the pool     */
285
        INFO_POOL_MINE= 0x40LL, /**< Auth. to view user and/or group objects  */
286
        INSTANTIATE   = 0x80LL, /**< Auth. to instantiate a VM from a TEMPLATE*/
287
        CHOWN         = 0x100LL /**< Auth. to change ownership of an object   */
288
    };
289

    
290
    static string Operation_to_str(Operation op)
291
    {
292
        switch (op)
293
        {
294
            case CREATE:            return "CREATE";
295
            case DELETE:            return "DELETE";
296
            case USE:               return "USE";
297
            case MANAGE:            return "MANAGE";
298
            case INFO:              return "INFO";
299
            case INFO_POOL:         return "INFO_POOL";
300
            case INFO_POOL_MINE:    return "INFO_POOL_MINE";
301
            case INSTANTIATE:       return "INSTANTIATE";
302
            case CHOWN:             return "CHOWN";
303
            default:                return "";
304
        }
305
    };
306

    
307
    /**
308
     *  OpenNebula objects to perform an Operation
309
     */
310
    enum Object
311
    {
312
        VM         = 0x1000000000LL,
313
        HOST       = 0x2000000000LL,
314
        NET        = 0x4000000000LL,
315
        IMAGE      = 0x8000000000LL,
316
        USER       = 0x10000000000LL,
317
        TEMPLATE   = 0x20000000000LL,
318
        GROUP      = 0x40000000000LL,
319
        ACL        = 0x80000000000LL
320
    };
321

    
322
    static string Object_to_str(Object ob)
323
    {
324
        switch (ob)
325
        {
326
            case VM:       return "VM" ; break;
327
            case HOST:     return "HOST" ; break;
328
            case NET:      return "NET" ; break;
329
            case IMAGE:    return "IMAGE" ; break;
330
            case USER:     return "USER" ; break;
331
            case TEMPLATE: return "TEMPLATE" ; break;
332
            case GROUP:    return "GROUP" ; break;
333
            default:       return "";
334
        }
335
    };
336

    
337
    /**
338
     *  Sets the challenge to authenticate an user
339
     *  @param challenge a driver specific authentication challenge
340
     */
341
    void add_authenticate(const string &_username,
342
                          const string &_password,
343
                          const string &_session)
344
    {
345
        username = _username;
346
        password = _password;
347
        session  = _session;
348
    }
349

    
350
    /**
351
     *  Adds a new authorization item to this request
352
     *
353
     *        OBJECT:OBJECT_ID:ACTION:OWNER:PUBLIC
354
     *
355
     *    @param ob the object over which the operation will be performed
356
     *    @param ob_id the object unique id
357
     *    @param op the operation to be authorized
358
     *    @param owner id of user that owns the object. For creates MUST equals
359
          uid, hosts owner is uid=0
360
     *    @param pub public attribute
361
     */
362
    void add_auth(Object        ob,
363
                  const string& ob_id,
364
                  Operation     op,
365
                  int           owner,
366
                  bool          pub);
367

    
368
    /**
369
     *  Adds a new authorization item to this requests
370
     */
371
    void add_auth(Object        ob,
372
                  int           ob_id,
373
                  Operation     op,
374
                  int           owner,
375
                  bool          pub)
376
    {
377
        ostringstream oss;
378
        oss << ob_id;
379

    
380
        add_auth(ob,oss.str(),op,owner,pub);
381
    };
382

    
383
    /**
384
     *  Gets the authorization requests in a single string
385
     *  @return a space separated list of auth requests.
386
     */
387
    string get_auths()
388
    {
389
        ostringstream oss;
390

    
391
        for (unsigned int i=0; i<auths.size(); i++)
392
        {
393
            oss << auths[i] << " ";
394
        }
395

    
396
        return oss.str();
397
    };
398

    
399
    /**
400
     *  Notify client that we have an answer for the request
401
     */
402
    void notify()
403
    {
404
        am.trigger(ActionListener::ACTION_FINALIZE,0);
405
    };
406

    
407
    /**
408
     *  Wait for the AuthRequest to be completed
409
     */
410
    void wait()
411
    {
412
        time_out = time(0) + AuthManager::time_out();
413

    
414
        am.loop(0,0);
415
    };
416

    
417
    bool plain_authorize()
418
    {
419
        return ( uid == 0 || self_authorize );
420
    }
421

    
422
    bool plain_authenticate()
423
    {
424
        return (password == session);
425
    }
426

    
427
    /**
428
     *  The result of the request, true if authorized or authenticated
429
     */
430
    bool            result;
431

    
432
    /**
433
     *  Error message for negative results
434
     */
435
    string          message;
436

    
437
    /**
438
     *  Time out
439
     */
440
    bool            timeout;
441

    
442
    /**
443
     *  Identification of this request
444
     */
445
    int             id;
446

    
447
private:
448

    
449
    friend class AuthManager;
450

    
451
    /**
452
     *  The ActionManager that will be notify when the request is ready.
453
     */
454
    ActionManager am;
455

    
456
    /**
457
     *  The user id for this request
458
     */
459
    int uid;
460

    
461
    /**
462
     *  Timeout for this request
463
     */
464
    time_t time_out;
465

    
466
    /**
467
     *  Username to authenticate the user
468
     */
469
    string username;
470

    
471
    /**
472
     *  User password to authenticate the user
473
     */
474
    string password;
475

    
476
    /**
477
     *  Authentication token as sent in the XML-RPC call (user:session)
478
     */
479
    string session;
480

    
481
    /**
482
     *  A list of authorization requests
483
     */
484
    vector<string> auths;
485

    
486
    /**
487
     *  Plain authorization for the request
488
     */
489
    bool self_authorize;
490

    
491
    /**
492
     *  No actions defined for the Auth request, just FINALIZE when done
493
     */
494
    void do_action(const string &name, void *args){};
495

    
496

    
497
};
498

    
499
#endif /*AUTH_MANAGER_H*/
500