aboutsummaryrefslogtreecommitdiff
path: root/lib/libtacplus/taclib.c
diff options
context:
space:
mode:
authorShteryana Shopova <syrinx@FreeBSD.org>2009-12-11 07:53:44 +0000
committerShteryana Shopova <syrinx@FreeBSD.org>2009-12-11 07:53:44 +0000
commitdb3a20a5183954a016ea8dd379c2fce2aaa2f9d1 (patch)
treef345d4d4a5390c125ee6b526c3d8bac3984aca9a /lib/libtacplus/taclib.c
parent57467e59336cecb6278637ab741895d0844e1956 (diff)
downloadsrc-db3a20a5183954a016ea8dd379c2fce2aaa2f9d1.tar.gz
src-db3a20a5183954a016ea8dd379c2fce2aaa2f9d1.zip
Add support for TACACS+ accounting to libtacplus(3).
Submitted by: Michael Pounov misho@aitbg.com OKed by: emaste
Notes
Notes: svn path=/head/; revision=200399
Diffstat (limited to 'lib/libtacplus/taclib.c')
-rw-r--r--lib/libtacplus/taclib.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/libtacplus/taclib.c b/lib/libtacplus/taclib.c
index a44e83476e88..ffe371a7f898 100644
--- a/lib/libtacplus/taclib.c
+++ b/lib/libtacplus/taclib.c
@@ -211,6 +211,8 @@ protocol_version(int msg_type, int var, int type)
}
break;
+ case TAC_ACCT:
+
default:
minor = 0;
break;
@@ -967,6 +969,23 @@ tac_create_author(struct tac_handle *h, int method, int type, int service)
return 0;
}
+int
+tac_create_acct(struct tac_handle *h, int acct, int action, int type, int service)
+{
+ struct tac_acct_start *as;
+
+ create_msg(h, TAC_ACCT, action, type);
+
+ as = &h->request.u.acct_start;
+ as->action = acct;
+ as->authen_action = action;
+ as->priv_lvl = TAC_PRIV_LVL_USER;
+ as->authen_type = type;
+ as->authen_service = service;
+
+ return 0;
+}
+
static void
create_msg(struct tac_handle *h, int msg_type, int var, int type)
{
@@ -1158,6 +1177,49 @@ tac_send_author(struct tac_handle *h)
}
int
+tac_send_acct(struct tac_handle *h)
+{
+ register int i, current;
+ struct tac_acct_start *as = &h->request.u.acct_start;
+ struct tac_acct_reply *ar = &h->response.u.acct_reply;
+
+ /* start */
+ as = &h->request.u.acct_start;
+ h->request.length = htonl(offsetof(struct tac_acct_start, rest[0]));
+ for (as->av_cnt = 0, i = 0; i < MAXAVPAIRS; i++)
+ if (h->avs[i].len && h->avs[i].data)
+ as->av_cnt++;
+ h->request.length = ntohl(htonl(h->request.length) + as->av_cnt);
+
+ if (add_str_8(h, &as->user_len, &h->user) == -1 ||
+ add_str_8(h, &as->port_len, &h->port) == -1 ||
+ add_str_8(h, &as->rem_addr_len, &h->rem_addr) == -1)
+ return -1;
+
+ for (i = current = 0; i < MAXAVPAIRS; i++)
+ if (h->avs[i].len && h->avs[i].data)
+ if (add_str_8(h, &as->rest[current++], &(h->avs[i])) == -1)
+ return -1;
+
+ /* send */
+ if (send_msg(h) == -1 || recv_msg(h) == -1)
+ return -1;
+
+ /* reply */
+ h->srvr_pos = offsetof(struct tac_acct_reply, rest[0]);
+ if (get_srvr_str(h, "msg", &h->srvr_msg, ntohs(ar->msg_len)) == -1 ||
+ get_srvr_str(h, "data", &h->srvr_data, ntohs(ar->data_len)) == -1 ||
+ get_srvr_end(h) == -1)
+ return -1;
+
+ /* Sanity checks */
+ if (!h->single_connect)
+ close_connection(h);
+
+ return ar->status;
+}
+
+int
tac_set_rem_addr(struct tac_handle *h, const char *addr)
{
return save_str(h, &h->rem_addr, addr, addr != NULL ? strlen(addr) : 0);