34
37
#include <unistd.h>
42
#include "pam_tacplus.h"
46
#define PAM_SM_ACCOUNT
47
#define PAM_SM_SESSION
48
/* #define PAM_SM_PASSWORD */
51
#include <security/pam_appl.h>
53
#include <security/pam_modules.h>
55
40
#ifdef HAVE_CONFIG_H
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);
76
extern u_int32_t magic();
78
44
/* address of server discovered by pam_sm_authenticate */
79
static struct addrinfo *active_server;
45
static tacplus_server_t active_server;
81
47
/* accounting task identifier */
82
48
static short int task_id = 0;
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) {
90
56
struct tac_attrib *attr;
93
attr=(struct tac_attrib *)_xcalloc(sizeof(struct tac_attrib));
96
sprintf(buf, "%d", time(0));
98
sprintf(buf, "%lu", (long unsigned int)time(0));
59
attr=(struct tac_attrib *)xcalloc(1, sizeof(struct tac_attrib));
61
sprintf(buf, "%lu", (unsigned long)time(NULL));
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);
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);
116
78
/* this is no longer needed */
117
79
tac_free_attrib(&attr);
156
123
ctrl = _pam_parse (argc, argv);
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);
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);
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)) {
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);
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);
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
242
209
for(srv_i = 0; srv_i < tac_srv_no; srv_i++) {
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);
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);
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
298
265
int status = PAM_AUTH_ERR;
300
user = pass = tty = rem_addr = NULL;
267
user = pass = tty = r_addr = NULL;
302
269
ctrl = _pam_parse (argc, argv);
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);
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);
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);
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 );
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) {
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;
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;
347
if (ctrl & PAM_TAC_DEBUG)
348
syslog (LOG_DEBUG, "%s: active srv %d", __FUNCTION__, srv_i );
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;
364
if (ctrl & PAM_TAC_DEBUG)
365
syslog (LOG_DEBUG, "%s: active srv %d", __FUNCTION__, srv_i );
414
389
int ctrl = _pam_parse (argc, argv);
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);
420
395
return PAM_SUCCESS;
432
407
int retval, ctrl, status=PAM_AUTH_ERR;
436
411
struct areply arep;
437
412
struct tac_attrib *attr = NULL;
440
user = tty = rem_addr = NULL;
415
user = tty = r_addr = NULL;
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);
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);
453
428
if ((user = _pam_get_user(pamh)) == NULL)
456
431
if (ctrl & PAM_TAC_DEBUG)
457
432
syslog(LOG_DEBUG, "%s: username obtained [%s]", __FUNCTION__, user);
459
434
tty = _pam_get_terminal(pamh);
460
435
if(!strncmp(tty, "/dev/", 5))
462
437
if (ctrl & PAM_TAC_DEBUG)
463
438
syslog(LOG_DEBUG, "%s: tty obtained [%s]", __FUNCTION__, tty);
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);
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
448
if(active_server.addr == NULL) {
474
449
_pam_log (LOG_ERR, "user not authenticated by TACACS+");
475
450
return PAM_AUTH_ERR;
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));
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;
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;
492
467
tac_add_attrib(&attr, "service", tac_service);
493
468
tac_add_attrib(&attr, "protocol", tac_protocol);
495
tac_fd = tac_connect_single(active_server, active_key);
470
tac_fd = tac_connect_single(active_server.addr, active_server.key);
497
472
_pam_log (LOG_ERR, "TACACS+ server unavailable");
498
if(arep.msg != NULL) free (arep.msg);
500
477
return PAM_AUTH_ERR;
503
retval = tac_author_send(tac_fd, user, tty, rem_addr, attr);
480
retval = tac_author_send(tac_fd, user, tty, r_addr, attr);
505
482
tac_free_attrib(&attr);
508
485
_pam_log (LOG_ERR, "error getting authorization");
509
if(arep.msg != NULL) free (arep.msg);
511
490
return PAM_AUTH_ERR;
610
595
int ctrl = _pam_parse (argc, argv);
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);
616
601
return PAM_SUCCESS;