aboutsummaryrefslogtreecommitdiff
path: root/lib
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
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')
-rw-r--r--lib/libtacplus/libtacplus.345
-rw-r--r--lib/libtacplus/taclib.c62
-rw-r--r--lib/libtacplus/taclib.h13
-rw-r--r--lib/libtacplus/taclib_private.h22
4 files changed, 142 insertions, 0 deletions
diff --git a/lib/libtacplus/libtacplus.3 b/lib/libtacplus/libtacplus.3
index 9ce6c4a1746b..1f6d6ac30d36 100644
--- a/lib/libtacplus/libtacplus.3
+++ b/lib/libtacplus/libtacplus.3
@@ -44,6 +44,8 @@
.Fn tac_create_authen "struct tac_handle *h" "int action" "int type" "int service"
.Ft int
.Fn tac_create_author "struct tac_handle *h" "int method" "int type" "int service"
+.Ft int
+.Fn tac_create_acct "struct tac_handle *h" "int acct" "int action" "int type" "int service"
.Ft char *
.Fn tac_get_av "struct tac_handle *h" "u_int index"
.Ft char *
@@ -59,6 +61,8 @@
.Ft int
.Fn tac_send_author "struct tac_handle *h"
.Ft int
+.Fn tac_send_acct "struct tac_handle *h"
+.Ft int
.Fn tac_set_av "struct tac_handle *h" "u_int index" "const char *av_pair"
.Ft int
.Fn tac_set_data "struct tac_handle *h" "const void *data" "size_t data_len"
@@ -193,6 +197,20 @@ TACACS+ protocol specification.
The
.In taclib.h
header file contains symbolic constants for these values.
+.Sh CREATING A TACACS+ ACCOUNTING REQUEST
+To begin constructing a new accounting request, call
+.Fn tac_create_acct .
+The
+.Va acct ,
+.Va action ,
+.Va type ,
+and
+.Va service
+arguments must be set to appropriate values as defined in the
+TACACS+ protocol specification.
+The
+.In taclib.h
+header file contains symbolic constants for these values.
.Sh SETTING OPTIONAL PARAMETERS ON A REQUEST
After creating a request,
various optional parameters may be attached to it through calls to
@@ -354,6 +372,29 @@ include:
.Pp
The number of AV pairs received is obtained using
.Fn TAC_AUTHEN_AV_COUNT .
+.Sh SENDING THE ACCOUNTING REQUEST AND RECEIVING THE RESPONSE
+After the TACACS+ authorization request has been constructed, it
+is sent by means of
+.Fn tac_send_acct .
+This function connects to a server if not already connected, sends
+the request, and waits for a reply.
+On failure,
+.Fn tac_send_acct
+returns \-1.
+Otherwise, it returns the TACACS+ status code
+Possible status codes, defined in
+.In taclib.h ,
+include:
+.Pp
+.Bl -item -compact -offset indent
+.It
+.Dv TAC_ACCT_STATUS_SUCCESS
+.It
+.Dv TAC_ACCT_STATUS_ERROR
+.It
+.Dv TAC_ACCT_STATUS_FOLLOW
+.El
+.Pp
.Sh EXTRACTING INFORMATION FROM THE SERVER'S AUTHORIZATION RESPONSE
Like an authentication response packet, an authorization
response packet from the
@@ -418,10 +459,14 @@ which can be retrieved using
.It
.Fn tac_create_author
.It
+.Fn tac_create_acct
+.It
.Fn tac_send_authen
.It
.Fn tac_send_author
.It
+.Fn tac_send_acct
+.It
.Fn tac_set_av
.It
.Fn tac_set_data
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);
diff --git a/lib/libtacplus/taclib.h b/lib/libtacplus/taclib.h
index 2ef36b9efd50..46b9a59d80a4 100644
--- a/lib/libtacplus/taclib.h
+++ b/lib/libtacplus/taclib.h
@@ -103,6 +103,17 @@ struct tac_handle;
#define TAC_AUTHOR_STATUS_FAIL 0x10
#define TAC_AUTHOR_STATUS_ERROR 0x11
+/* Accounting actions */
+#define TAC_ACCT_MORE 0x1
+#define TAC_ACCT_START 0x2
+#define TAC_ACCT_STOP 0x4
+#define TAC_ACCT_WATCHDOG 0x8
+
+/* Accounting status */
+#define TAC_ACCT_STATUS_SUCCESS 0x1
+#define TAC_ACCT_STATUS_ERROR 0x2
+#define TAC_ACCT_STATUS_FOLLOW 0x21
+
__BEGIN_DECLS
int tac_add_server(struct tac_handle *,
const char *, int, const char *, int, int);
@@ -127,6 +138,8 @@ int tac_set_av(struct tac_handle *, u_int, const char *);
char *tac_get_av(struct tac_handle *, u_int);
char *tac_get_av_value(struct tac_handle *, const char *);
void tac_clear_avs(struct tac_handle *);
+int tac_create_acct(struct tac_handle *, int, int, int, int);
+int tac_send_acct(struct tac_handle *);
__END_DECLS
#endif /* _TACLIB_H_ */
diff --git a/lib/libtacplus/taclib_private.h b/lib/libtacplus/taclib_private.h
index bbc1990c9269..2730023a632a 100644
--- a/lib/libtacplus/taclib_private.h
+++ b/lib/libtacplus/taclib_private.h
@@ -132,6 +132,26 @@ struct tac_author_response {
unsigned char rest[1];
};
+struct tac_acct_start {
+ u_int8_t action;
+ u_int8_t authen_action;
+ u_int8_t priv_lvl;
+ u_int8_t authen_type;
+ u_int8_t authen_service;
+ u_int8_t user_len;
+ u_int8_t port_len;
+ u_int8_t rem_addr_len;
+ u_int8_t av_cnt;
+ unsigned char rest[1];
+};
+
+struct tac_acct_reply {
+ u_int16_t msg_len;
+ u_int16_t data_len;
+ u_int8_t status;
+ unsigned char rest[1];
+};
+
struct tac_msg {
u_int8_t version;
u_int8_t type;
@@ -145,6 +165,8 @@ struct tac_msg {
struct tac_authen_cont authen_cont;
struct tac_author_request author_request;
struct tac_author_response author_response;
+ struct tac_acct_start acct_start;
+ struct tac_acct_reply acct_reply;
unsigned char body[BODYSIZE];
} u;
};