Statistics
| Branch: | Tag: | Revision:

one / src / authm / AuthManager.cc @ 01d932ad

History | View | Annotate | Download (12.8 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
#include "AuthManager.h"
18
#include "NebulaLog.h"
19
#include "SSLTools.h"
20

    
21
#include "Nebula.h"
22

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

    
26
time_t AuthManager::_time_out;
27

    
28
const char * AuthManager::auth_driver_name = "auth_exe";
29

    
30
/* -------------------------------------------------------------------------- */
31
/* -------------------------------------------------------------------------- */
32

    
33
void AuthRequest::add_auth(Object        ob,
34
                           const string& ob_id,
35
                           Operation     op,
36
                           int           owner,
37
                           bool          pub)
38
{
39
    ostringstream oss;
40
    bool          auth;
41

    
42
    switch (ob)
43
    {
44
        case VM:       oss << "VM:" ; break;
45
        case HOST:     oss << "HOST:" ; break;
46
        case NET:      oss << "NET:" ; break;
47
        case IMAGE:    oss << "IMAGE:" ; break;
48
        case USER:     oss << "USER:" ; break;
49
        case CLUSTER:  oss << "CLUSTER:" ; break;
50
        case TEMPLATE: oss << "TEMPLATE:" ; break;
51
        case GROUP:    oss << "GROUP:" ; break;
52
    }
53

    
54
    if (op == CREATE || op == INSTANTIATE) //encode the ob_id, it is a template
55
    {
56
        string * encoded_id = SSLTools::base64_encode(ob_id);
57

    
58
        if (encoded_id != 0)
59
        {
60
            oss << *encoded_id << ":";
61
            delete (encoded_id);
62
        }
63
        else
64
        {
65
            oss << "-:";
66
        }
67
    }
68
    else
69
    {
70
        oss << ob_id << ":";
71
    }
72

    
73
    switch (op)
74
    {
75
        case CREATE:
76
            oss << "CREATE:" ;
77
            break;
78

    
79
        case DELETE:
80
            oss << "DELETE:" ;
81
            break;
82

    
83
        case USE:
84
            oss << "USE:" ;
85
            break;
86

    
87
        case MANAGE:
88
            oss << "MANAGE:" ;
89
            break;
90
            
91
        case INFO:
92
            oss << "INFO:" ;
93
            break;
94

    
95
        case INFO_POOL:
96
            oss << "INFO_POOL:" ;
97
            break;
98

    
99
        case INSTANTIATE:
100
            oss << "INSTANTIATE:" ;
101
            break;
102
    }
103

    
104
    oss << owner << ":" << pub;
105

    
106
    // -------------------------------------------------------------------------
107
    // Authorize the request for self authorization
108
    // -------------------------------------------------------------------------
109

    
110
    if ( uid == 0 )
111
    {
112
        auth = true;
113
    }
114
    else
115
    {
116
        auth = false;
117

    
118
        switch (op)
119
        {
120
            case CREATE:
121
                if ( ob == VM || ob == NET || ob == IMAGE || ob == TEMPLATE )
122
                {
123
                    auth = true;
124
                }
125
                break;
126

    
127
            case INSTANTIATE:
128
                if ( ob == VM )
129
                {
130
                    auth = true;
131
                }
132
                break;
133

    
134
            case DELETE:
135
                auth = owner == uid;
136
                break;
137

    
138
            case USE:
139
                if (ob == NET || ob == IMAGE || ob == TEMPLATE)
140
                {
141
                    auth = (owner == uid) || pub;
142
                }
143
                else if (ob == HOST)
144
                {
145
                    auth = true;
146
                }
147
                break;
148

    
149
            case MANAGE:
150
                auth = owner == uid;
151
                break;
152
                
153
            case INFO: // This is for completeness, as the only INFO existing 
154
                       // is for UserPool, and just oneadmin can see it
155
                break;
156

    
157
            case INFO_POOL:
158
                if ( ob != USER )
159
                {
160
                    auth = true;
161
                }
162
                break;
163
        }
164
    }
165

    
166
    self_authorize = self_authorize && auth;
167

    
168
    auths.push_back(oss.str());
169
}
170

    
171
/* -------------------------------------------------------------------------- */
172
/* -------------------------------------------------------------------------- */
173

    
174
extern "C" void * authm_action_loop(void *arg)
175
{
176
    AuthManager *  authm;
177

    
178
    if ( arg == 0 )
179
    {
180
        return 0;
181
    }
182

    
183
    authm = static_cast<AuthManager *>(arg);
184

    
185
    NebulaLog::log("AuM",Log::INFO,"Authorization Manager started.");
186

    
187
    authm->am.loop(authm->timer_period,0);
188

    
189
    NebulaLog::log("AuM",Log::INFO,"Authorization Manager stopped.");
190

    
191
    return 0;
192
}
193

    
194
/* -------------------------------------------------------------------------- */
195

    
196
int AuthManager::start()
197
{
198
    int               rc;
199
    pthread_attr_t    pattr;
200

    
201
    rc = MadManager::start();
202

    
203
    if ( rc != 0 )
204
    {
205
        return -1;
206
    }
207

    
208
    NebulaLog::log("AuM",Log::INFO,"Starting Auth Manager...");
209

    
210
    pthread_attr_init (&pattr);
211
    pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE);
212

    
213
    rc = pthread_create(&authm_thread,&pattr,authm_action_loop,(void *) this);
214

    
215
    return rc;
216
}
217

    
218
/* -------------------------------------------------------------------------- */
219
/* -------------------------------------------------------------------------- */
220

    
221
void AuthManager::trigger(Actions action, AuthRequest * request)
222
{
223
    string  aname;
224

    
225
    switch (action)
226
    {
227
    case AUTHENTICATE:
228
        aname = "AUTHENTICATE";
229
        break;
230

    
231
    case AUTHORIZE:
232
        aname = "AUTHORIZE";
233
        break;
234

    
235
    case FINALIZE:
236
        aname = ACTION_FINALIZE;
237
        break;
238

    
239
    default:
240
        return;
241
    }
242

    
243
    am.trigger(aname,request);
244
}
245

    
246
/* -------------------------------------------------------------------------- */
247
/* -------------------------------------------------------------------------- */
248

    
249
void AuthManager::do_action(const string &action, void * arg)
250
{
251
    AuthRequest * request;
252

    
253
    request  = static_cast<AuthRequest *>(arg);
254

    
255
    if (action == "AUTHENTICATE" && request != 0)
256
    {
257
        authenticate_action(request);
258
    }
259
    else if (action == "AUTHORIZE"  && request != 0)
260
    {
261
        authorize_action(request);
262
    }
263
    else if (action == ACTION_TIMER)
264
    {
265
        timer_action();
266
    }
267
    else if (action == ACTION_FINALIZE)
268
    {
269
        NebulaLog::log("AuM",Log::INFO,"Stopping Authorization Manager...");
270

    
271
        MadManager::stop();
272
    }
273
    else
274
    {
275
        ostringstream oss;
276
        oss << "Unknown action name: " << action;
277

    
278
        NebulaLog::log("AuM", Log::ERROR, oss);
279
    }
280
}
281

    
282
/* -------------------------------------------------------------------------- */
283
/* -------------------------------------------------------------------------- */
284

    
285
void AuthManager::authenticate_action(AuthRequest * ar)
286
{
287
    const AuthManagerDriver * authm_md;
288

    
289
    // ------------------------------------------------------------------------
290
    // Get the driver
291
    // ------------------------------------------------------------------------
292

    
293
    authm_md = get();
294

    
295
    if (authm_md == 0)
296
    {
297
        goto error_driver;
298
    }
299

    
300
    // ------------------------------------------------------------------------
301
    // Queue the request
302
    // ------------------------------------------------------------------------
303

    
304
    ar->id = add_request(ar);
305

    
306
    // ------------------------------------------------------------------------
307
    // Make the request to the driver
308
    // ---- --------------------------------------------------------------------
309

    
310

    
311
    authm_md->authenticate(ar->id,
312
                           ar->uid,
313
                           ar->username,
314
                           ar->password,
315
                           ar->session);
316
    return;
317

    
318
error_driver:
319
    ar->result  = false;
320
    ar->message = "Could not find Authorization driver";
321
    ar->notify();
322
}
323

    
324
/* -------------------------------------------------------------------------- */
325
/* -------------------------------------------------------------------------- */
326

    
327
void AuthManager::authorize_action(AuthRequest * ar)
328
{
329
    const AuthManagerDriver * authm_md;
330
    string auths;
331

    
332
    // ------------------------------------------------------------------------
333
    // Get the driver
334
    // ------------------------------------------------------------------------
335

    
336
    authm_md = get();
337

    
338
    if (authm_md == 0)
339
    {
340
        goto error_driver;
341
    }
342

    
343
    // ------------------------------------------------------------------------
344
    // Queue the request
345
    // ------------------------------------------------------------------------
346

    
347
    ar->id = add_request(ar);
348

    
349
    // ------------------------------------------------------------------------
350
    // Make the request to the driver
351
    // ------------------------------------------------------------------------
352

    
353
    auths = ar->get_auths();
354

    
355
    authm_md->authorize(ar->id, ar->uid, auths);
356

    
357
    return;
358

    
359
error_driver:
360
    ar->result  = false;
361
    ar->message = "Could not find Authorization driver";
362
    ar->notify();
363
}
364
/* -------------------------------------------------------------------------- */
365
/* -------------------------------------------------------------------------- */
366

    
367
void AuthManager::timer_action()
368
{
369
    map<int,AuthRequest *>::iterator it;
370

    
371
    time_t the_time = time(0);
372

    
373
    lock();
374

    
375
    it = auth_requests.begin();
376

    
377
    while ( it !=auth_requests.end())
378
    {
379
        if (the_time > it->second->time_out)
380
        {
381
            AuthRequest * ar = it->second;
382
            auth_requests.erase(it++);
383

    
384
            ar->result  = false;
385
            ar->timeout = true;
386
            ar->message = "Auth request timeout";
387

    
388
            ar->notify();
389
        }
390
        else
391
        {
392
            ++it;
393
        }
394
    }
395

    
396
    unlock();
397

    
398
}
399

    
400
/* -------------------------------------------------------------------------- */
401
/* -------------------------------------------------------------------------- */
402

    
403
int AuthManager::add_request(AuthRequest *ar)
404
{
405
    static int auth_id = 0;
406
    int id;
407

    
408
    lock();
409

    
410
    id = auth_id++;
411

    
412
    auth_requests.insert(auth_requests.end(),make_pair(id,ar));
413

    
414
    unlock();
415

    
416
    return id;
417
}
418

    
419
/* -------------------------------------------------------------------------- */
420
/* -------------------------------------------------------------------------- */
421

    
422
AuthRequest * AuthManager::get_request(int id)
423
{
424
    AuthRequest * ar = 0;
425
    map<int,AuthRequest *>::iterator it;
426
    ostringstream oss;
427

    
428
    lock();
429

    
430
    it=auth_requests.find(id);
431

    
432
    if ( it != auth_requests.end())
433
    {
434
        ar = it->second;
435

    
436
        auth_requests.erase(it);
437
    }
438

    
439
    unlock();
440

    
441
    return ar;
442
}
443

    
444
/* -------------------------------------------------------------------------- */
445
/* -------------------------------------------------------------------------- */
446

    
447
void AuthManager::notify_request(int auth_id,bool result,const string& message)
448
{
449

    
450
    AuthRequest * ar;
451

    
452
    ar = get_request(auth_id);
453

    
454
    if ( ar == 0 )
455
    {
456
        return;
457
    }
458

    
459
    ar->result = result;
460
    ar->message= message;
461

    
462
    ar->notify();
463
}
464

    
465
/* ************************************************************************** */
466
/* MAD Loading                                                                */
467
/* ************************************************************************** */
468

    
469
void AuthManager::load_mads(int uid)
470
{
471
    ostringstream                   oss;
472
    const VectorAttribute *         vattr;
473
    int                             rc;
474
    string                          name;
475
    AuthManagerDriver *             authm_driver = 0;
476

    
477
    oss << "Loading Auth. Manager driver.";
478

    
479
    NebulaLog::log("AuM",Log::INFO,oss);
480

    
481
    vattr = static_cast<const VectorAttribute *>(mad_conf[0]);
482

    
483
    if ( vattr == 0 )
484
    {
485
        NebulaLog::log("AuM",Log::ERROR,"Failed to load Auth. Manager driver.");
486
        return;
487
    }
488

    
489
    VectorAttribute auth_conf("AUTH_MAD",vattr->value());
490

    
491
    auth_conf.replace("NAME",auth_driver_name);
492

    
493
    authm_driver = new AuthManagerDriver(uid,auth_conf.value(),(uid!=0),this);
494

    
495
    rc = add(authm_driver);
496

    
497
    if ( rc == 0 )
498
    {
499
        oss.str("");
500
        oss << "\tAuth Manager loaded";
501

    
502
        NebulaLog::log("AuM",Log::INFO,oss);
503
    }
504
}