~ubuntu-branches/ubuntu/utopic/libpam-tacplus/utopic

« back to all changes in this revision

Viewing changes to pam_tacplus.c

  • Committer: Package Import Robot
  • Author(s): Jeroen Nijhof
  • Date: 2014-01-31 12:32:00 UTC
  • mfrom: (4.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140131123200-slruika7jmfmyfp6
Tags: 1.3.8-1
* New upstream release.
* Fixed pam-configs. Closes: #717716
* Added dh-autoreconf. Closes: #734228

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 * See `CHANGES' file for revision history.
20
20
 */
21
21
 
 
22
#include "pam_tacplus.h"
 
23
#include "support.h"
 
24
 
22
25
#include <stdlib.h>     /* malloc */
23
26
#include <stdio.h>
24
27
#include <syslog.h>
32
35
#include <ctype.h>
33
36
#include <time.h>
34
37
#include <unistd.h>
35
 
 
36
 
#ifndef __linux__
37
 
    #include <strings.h>
38
 
#endif
39
 
 
40
 
#include "tacplus.h"
41
 
#include "libtac.h"
42
 
#include "pam_tacplus.h"
43
 
#include "support.h"
44
 
 
45
 
#define PAM_SM_AUTH
46
 
#define PAM_SM_ACCOUNT
47
 
#define PAM_SM_SESSION
48
 
/* #define PAM_SM_PASSWORD */
49
 
 
50
 
#ifndef __linux__
51
 
    #include <security/pam_appl.h>
52
 
#endif
53
 
#include <security/pam_modules.h>
 
38
#include <strings.h>
54
39
 
55
40
#ifdef HAVE_CONFIG_H
56
 
    #include "config.h"
 
41
  #include "config.h"
57
42
#endif
58
43
 
59
 
/* support.c */
60
 
extern struct addrinfo *tac_srv[TAC_PLUS_MAXSERVERS];
61
 
extern char *tac_srv_key[TAC_PLUS_MAXSERVERS];
62
 
extern int tac_srv_no;
63
 
extern char *tac_service;
64
 
extern char *tac_protocol;
65
 
extern int _pam_parse (int argc, const char **argv);
66
 
extern unsigned long _getserveraddr (char *serv);
67
 
extern int tacacs_get_password (pam_handle_t * pamh, int flags
68
 
    ,int ctrl, char **password);
69
 
extern int converse (pam_handle_t * pamh, int nargs
70
 
    ,struct pam_message **message
71
 
    ,struct pam_response **response);
72
 
extern void _pam_log (int err, const char *format,...);
73
 
extern void *_xcalloc (size_t size);
74
 
 
75
 
/* magic.c */
76
 
extern u_int32_t magic();
77
 
 
78
44
/* address of server discovered by pam_sm_authenticate */
79
 
static struct addrinfo *active_server;
80
 
char *active_key;
 
45
static tacplus_server_t active_server;
 
46
 
81
47
/* accounting task identifier */
82
48
static short int task_id = 0;
83
49
 
84
50
 
85
51
/* Helper functions */
86
52
int _pam_send_account(int tac_fd, int type, const char *user, char *tty,
87
 
    char *rem_addr, char *cmd) {
 
53
    char *r_addr, char *cmd) {
88
54
 
89
 
    char buf[40];
 
55
    char buf[64];
90
56
    struct tac_attrib *attr;
91
57
    int retval;
92
 
        
93
 
    attr=(struct tac_attrib *)_xcalloc(sizeof(struct tac_attrib));
94
 
        
95
 
#ifdef _AIX
96
 
    sprintf(buf, "%d", time(0));
97
 
#else
98
 
    sprintf(buf, "%lu", (long unsigned int)time(0));
99
 
#endif
 
58
 
 
59
    attr=(struct tac_attrib *)xcalloc(1, sizeof(struct tac_attrib));
 
60
 
 
61
    sprintf(buf, "%lu", (unsigned long)time(NULL));
100
62
 
101
63
    if (type == TAC_PLUS_ACCT_FLAG_START) {
102
64
        tac_add_attrib(&attr, "start_time", buf);
111
73
        tac_add_attrib(&attr, "cmd", cmd);
112
74
    }
113
75
 
114
 
    retval = tac_acct_send(tac_fd, type, user, tty, rem_addr, attr);
 
76
    retval = tac_acct_send(tac_fd, type, user, tty, r_addr, attr);
115
77
 
116
78
    /* this is no longer needed */
117
79
    tac_free_attrib(&attr);
131
93
            __FUNCTION__, 
132
94
            tac_acct_flag2str(type),
133
95
            task_id);
134
 
        if(re.msg != NULL) free(re.msg);
 
96
 
 
97
        if(re.msg != NULL)
 
98
            free(re.msg);
 
99
 
135
100
        close(tac_fd);
136
101
        return -1;
137
102
    }
138
103
 
139
 
    if(re.msg != NULL) free(re.msg);
 
104
    if(re.msg != NULL)
 
105
        free(re.msg);
 
106
 
140
107
    close(tac_fd);
141
108
    return 0;
142
109
}
148
115
    static int ctrl;
149
116
    char *user = NULL;
150
117
    char *tty = NULL;
151
 
    char *rem_addr = NULL;
 
118
    char *r_addr = NULL;
152
119
    char *typemsg;
153
120
    int status = PAM_SESSION_ERR;
154
121
  
156
123
    ctrl = _pam_parse (argc, argv);
157
124
 
158
125
    if (ctrl & PAM_TAC_DEBUG)
159
 
        syslog (LOG_DEBUG, "%s: [%s] called (pam_tacplus v%hu.%hu.%hu)"
 
126
        syslog (LOG_DEBUG, "%s: [%s] called (pam_tacplus v%u.%u.%u)"
160
127
            , __FUNCTION__, typemsg, PAM_TAC_VMAJ, PAM_TAC_VMIN, PAM_TAC_VPAT);
161
128
    if (ctrl & PAM_TAC_DEBUG)
162
129
        syslog(LOG_DEBUG, "%s: tac_srv_no=%d", __FUNCTION__, tac_srv_no);
173
140
    if (ctrl & PAM_TAC_DEBUG)
174
141
        syslog(LOG_DEBUG, "%s: tty [%s] obtained", __FUNCTION__, tty);
175
142
 
176
 
    rem_addr = _pam_get_rhost(pamh);
 
143
    r_addr = _pam_get_rhost(pamh);
177
144
    if (ctrl & PAM_TAC_DEBUG)
178
 
        syslog(LOG_DEBUG, "%s: rhost [%s] obtained", __FUNCTION__, rem_addr);
 
145
        syslog(LOG_DEBUG, "%s: rhost [%s] obtained", __FUNCTION__, r_addr);
179
146
 
180
147
    /* checks for specific data required by TACACS+, which should
181
148
       be supplied in command line  */
207
174
        while ((status == PAM_SESSION_ERR) && (srv_i < tac_srv_no)) {
208
175
            int tac_fd;
209
176
                                  
210
 
            tac_fd = tac_connect_single(tac_srv[srv_i], tac_srv_key[srv_i]);
 
177
            tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key);
211
178
            if(tac_fd < 0) {
212
179
                _pam_log(LOG_WARNING, "%s: error sending %s (fd)",
213
180
                    __FUNCTION__, typemsg);
218
185
            if (ctrl & PAM_TAC_DEBUG)
219
186
                syslog(LOG_DEBUG, "%s: connected with fd=%d (srv %d)", __FUNCTION__, tac_fd, srv_i);
220
187
 
221
 
            retval = _pam_send_account(tac_fd, type, user, tty, rem_addr, cmd);
 
188
            retval = _pam_send_account(tac_fd, type, user, tty, r_addr, cmd);
222
189
            /* return code from function in this mode is
223
190
               status of the last server we tried to send
224
191
               packet to */
242
209
        for(srv_i = 0; srv_i < tac_srv_no; srv_i++) {
243
210
            int tac_fd;
244
211
                                  
245
 
            tac_fd = tac_connect_single(tac_srv[srv_i], tac_srv_key[srv_i]);
 
212
            tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key);
246
213
            if(tac_fd < 0) {
247
214
                _pam_log(LOG_WARNING, "%s: error sending %s (fd)",
248
215
                    __FUNCTION__, typemsg);
252
219
            if (ctrl & PAM_TAC_DEBUG)
253
220
                syslog(LOG_DEBUG, "%s: connected with fd=%d (srv %d)", __FUNCTION__, tac_fd, srv_i);
254
221
 
255
 
            retval = _pam_send_account(tac_fd, type, user, tty, rem_addr, cmd);
 
222
            retval = _pam_send_account(tac_fd, type, user, tty, r_addr, cmd);
256
223
            /* return code from function in this mode is
257
224
               status of the last server we tried to send
258
225
               packet to */
292
259
    char *user;
293
260
    char *pass;
294
261
    char *tty;
295
 
    char *rem_addr;
 
262
    char *r_addr;
296
263
    int srv_i;
297
264
    int tac_fd;
298
265
    int status = PAM_AUTH_ERR;
299
266
 
300
 
    user = pass = tty = rem_addr = NULL;
 
267
    user = pass = tty = r_addr = NULL;
301
268
 
302
269
    ctrl = _pam_parse (argc, argv);
303
270
 
304
271
    if (ctrl & PAM_TAC_DEBUG)
305
 
        syslog (LOG_DEBUG, "%s: called (pam_tacplus v%hu.%hu.%hu)"
 
272
        syslog (LOG_DEBUG, "%s: called (pam_tacplus v%u.%u.%u)"
306
273
            , __FUNCTION__, PAM_TAC_VMAJ, PAM_TAC_VMIN, PAM_TAC_VPAT);
307
274
 
308
275
    if ((user = _pam_get_user(pamh)) == NULL)
334
301
    if (ctrl & PAM_TAC_DEBUG)
335
302
        syslog (LOG_DEBUG, "%s: tty [%s] obtained", __FUNCTION__, tty);
336
303
 
337
 
    rem_addr = _pam_get_rhost(pamh);
 
304
    r_addr = _pam_get_rhost(pamh);
338
305
    if (ctrl & PAM_TAC_DEBUG)
339
 
        syslog (LOG_DEBUG, "%s: rhost [%s] obtained", __FUNCTION__, rem_addr);
 
306
        syslog (LOG_DEBUG, "%s: rhost [%s] obtained", __FUNCTION__, r_addr);
340
307
 
341
308
    for (srv_i = 0; srv_i < tac_srv_no; srv_i++) {
342
309
        int msg = TAC_PLUS_AUTHEN_STATUS_FAIL;
343
310
        if (ctrl & PAM_TAC_DEBUG)
344
311
            syslog (LOG_DEBUG, "%s: trying srv %d", __FUNCTION__, srv_i );
345
312
 
346
 
        tac_fd = tac_connect_single(tac_srv[srv_i], tac_srv_key[srv_i]);
 
313
        tac_fd = tac_connect_single(tac_srv[srv_i].addr, tac_srv[srv_i].key);
347
314
        if (tac_fd < 0) {
348
315
            _pam_log (LOG_ERR, "connection failed srv %d: %m", srv_i);
349
316
            if (srv_i == tac_srv_no-1) {
353
320
            continue;
354
321
        }
355
322
 
356
 
        if (tac_authen_send(tac_fd, user, pass, tty, rem_addr) < 0) {
 
323
        if (tac_authen_send(tac_fd, user, pass, tty, r_addr) < 0) {
357
324
            _pam_log (LOG_ERR, "error sending auth req to TACACS+ server");
358
325
            status = PAM_AUTHINFO_UNAVAIL;
359
326
        } else {
373
340
                        /* OK, we got authenticated; save the server that
374
341
                           accepted us for pam_sm_acct_mgmt and exit the loop */
375
342
                        status = PAM_SUCCESS;
376
 
                        active_server = tac_srv[srv_i];
377
 
                        active_key = tac_srv_key[srv_i];
 
343
                        active_server.addr = tac_srv[srv_i].addr;
 
344
                        active_server.key = tac_srv[srv_i].key;
378
345
                        close(tac_fd);
 
346
 
 
347
                        if (ctrl & PAM_TAC_DEBUG)
 
348
                            syslog (LOG_DEBUG, "%s: active srv %d", __FUNCTION__, srv_i );
 
349
 
379
350
                        break;
380
351
                    }
381
352
                }
386
357
                /* OK, we got authenticated; save the server that
387
358
                   accepted us for pam_sm_acct_mgmt and exit the loop */
388
359
                status = PAM_SUCCESS;
389
 
                active_server = tac_srv[srv_i];
390
 
                active_key = tac_srv_key[srv_i];
 
360
                active_server.addr = tac_srv[srv_i].addr;
 
361
                active_server.key = tac_srv[srv_i].key;
391
362
                close(tac_fd);
 
363
 
 
364
                if (ctrl & PAM_TAC_DEBUG)
 
365
                    syslog (LOG_DEBUG, "%s: active srv %d", __FUNCTION__, srv_i );
 
366
 
392
367
                break;
393
368
            }
394
369
        }
414
389
    int ctrl = _pam_parse (argc, argv);
415
390
 
416
391
    if (ctrl & PAM_TAC_DEBUG)
417
 
        syslog (LOG_DEBUG, "%s: called (pam_tacplus v%hu.%hu.%hu)"
 
392
        syslog (LOG_DEBUG, "%s: called (pam_tacplus v%u.%u.%u)"
418
393
            , __FUNCTION__, PAM_TAC_VMAJ, PAM_TAC_VMIN, PAM_TAC_VPAT);
419
394
 
420
395
    return PAM_SUCCESS;
432
407
    int retval, ctrl, status=PAM_AUTH_ERR;
433
408
    char *user;
434
409
    char *tty;
435
 
    char *rem_addr;
 
410
    char *r_addr;
436
411
    struct areply arep;
437
412
    struct tac_attrib *attr = NULL;
438
413
    int tac_fd;
439
414
 
440
 
    user = tty = rem_addr = NULL;
 
415
    user = tty = r_addr = NULL;
441
416
  
442
417
    /* this also obtains service name for authorization
443
418
       this should be normally performed by pam_get_item(PAM_SERVICE)
447
422
    ctrl = _pam_parse (argc, argv);
448
423
 
449
424
    if (ctrl & PAM_TAC_DEBUG)
450
 
        syslog (LOG_DEBUG, "%s: called (pam_tacplus v%hu.%hu.%hu)"
 
425
        syslog (LOG_DEBUG, "%s: called (pam_tacplus v%u.%u.%u)"
451
426
            , __FUNCTION__, PAM_TAC_VMAJ, PAM_TAC_VMIN, PAM_TAC_VPAT);
452
427
  
453
428
    if ((user = _pam_get_user(pamh)) == NULL)
455
430
 
456
431
    if (ctrl & PAM_TAC_DEBUG)
457
432
        syslog(LOG_DEBUG, "%s: username obtained [%s]", __FUNCTION__, user);
458
 
  
 
433
 
459
434
    tty = _pam_get_terminal(pamh);
460
435
    if(!strncmp(tty, "/dev/", 5)) 
461
436
        tty += 5;
462
437
    if (ctrl & PAM_TAC_DEBUG)
463
438
        syslog(LOG_DEBUG, "%s: tty obtained [%s]", __FUNCTION__, tty);
464
439
 
465
 
    rem_addr = _pam_get_rhost(pamh);
 
440
    r_addr = _pam_get_rhost(pamh);
466
441
    if (ctrl & PAM_TAC_DEBUG)
467
 
        syslog(LOG_DEBUG, "%s: rhost obtained [%s]", __FUNCTION__, rem_addr);
 
442
        syslog(LOG_DEBUG, "%s: rhost obtained [%s]", __FUNCTION__, r_addr);
468
443
  
469
444
    /* checks if user has been successfully authenticated
470
445
       by TACACS+; we cannot solely authorize user if it hasn't
471
446
       been authenticated or has been authenticated by method other
472
447
       than TACACS+ */
473
 
    if(!active_server) {
 
448
    if(active_server.addr == NULL) {
474
449
        _pam_log (LOG_ERR, "user not authenticated by TACACS+");
475
450
        return PAM_AUTH_ERR;
476
451
    }
477
452
    if (ctrl & PAM_TAC_DEBUG)
478
453
        syslog (LOG_DEBUG, "%s: active server is [%s]", __FUNCTION__,
479
 
            tac_ntop(active_server->ai_addr, active_server->ai_addrlen));
 
454
            tac_ntop(active_server.addr->ai_addr));
480
455
 
481
456
    /* checks for specific data required by TACACS+, which should
482
457
       be supplied in command line  */
483
 
    if(tac_service == NULL || *tac_service == '\0') {
 
458
    if(tac_service == NULL || !*tac_service) {
484
459
        _pam_log (LOG_ERR, "TACACS+ service type not configured");
485
460
        return PAM_AUTH_ERR;
486
461
    }
487
 
    if(tac_protocol == NULL || *tac_protocol == '\0') {
 
462
    if(tac_protocol == NULL || !*tac_protocol) {
488
463
        _pam_log (LOG_ERR, "TACACS+ protocol type not configured");
489
464
        return PAM_AUTH_ERR;
490
465
    }
492
467
    tac_add_attrib(&attr, "service", tac_service);
493
468
    tac_add_attrib(&attr, "protocol", tac_protocol);
494
469
 
495
 
    tac_fd = tac_connect_single(active_server, active_key);
 
470
    tac_fd = tac_connect_single(active_server.addr, active_server.key);
496
471
    if(tac_fd < 0) {
497
472
        _pam_log (LOG_ERR, "TACACS+ server unavailable");
498
 
        if(arep.msg != NULL) free (arep.msg);
 
473
        if(arep.msg != NULL)
 
474
            free (arep.msg);
 
475
 
499
476
        close(tac_fd);
500
477
        return PAM_AUTH_ERR;
501
478
    }
502
479
 
503
 
    retval = tac_author_send(tac_fd, user, tty, rem_addr, attr);
 
480
    retval = tac_author_send(tac_fd, user, tty, r_addr, attr);
504
481
 
505
482
    tac_free_attrib(&attr);
506
483
  
507
484
    if(retval < 0) {
508
485
        _pam_log (LOG_ERR, "error getting authorization");
509
 
        if(arep.msg != NULL) free (arep.msg);
 
486
        if(arep.msg != NULL)
 
487
            free (arep.msg);
 
488
 
510
489
        close(tac_fd);
511
490
        return PAM_AUTH_ERR;
512
491
    }
520
499
        arep.status != AUTHOR_STATUS_PASS_REPL) {
521
500
 
522
501
        _pam_log (LOG_ERR, "TACACS+ authorisation failed for [%s]", user);
523
 
        if(arep.msg != NULL) free (arep.msg);
 
502
        if(arep.msg != NULL)
 
503
            free (arep.msg);
 
504
 
524
505
        close(tac_fd);
525
506
        return PAM_PERM_DENIED;
526
507
    }
566
547
    }
567
548
 
568
549
    /* free returned attributes */
569
 
    if(arep.attr != NULL) tac_free_attrib(&arep.attr);
570
 
    if(arep.msg != NULL) free (arep.msg);
 
550
    if(arep.attr != NULL)
 
551
        tac_free_attrib(&arep.attr);
 
552
 
 
553
    if(arep.msg != NULL)
 
554
        free (arep.msg);
 
555
 
571
556
    close(tac_fd);
572
557
 
573
558
    return status;
610
595
    int ctrl = _pam_parse (argc, argv);
611
596
 
612
597
    if (ctrl & PAM_TAC_DEBUG)
613
 
        syslog (LOG_DEBUG, "%s: called (pam_tacplus v%hu.%hu.%hu)"
 
598
        syslog (LOG_DEBUG, "%s: called (pam_tacplus v%u.%u.%u)"
614
599
            , __FUNCTION__, PAM_TAC_VMAJ, PAM_TAC_VMIN, PAM_TAC_VPAT);
615
600
 
616
601
    return PAM_SUCCESS;