diff options
Diffstat (limited to 'libtac/lib/acct_s.c')
-rw-r--r-- | libtac/lib/acct_s.c | 255 |
1 files changed, 132 insertions, 123 deletions
diff --git a/libtac/lib/acct_s.c b/libtac/lib/acct_s.c index 5ca07c3..dd3dff9 100644 --- a/libtac/lib/acct_s.c +++ b/libtac/lib/acct_s.c @@ -1,6 +1,6 @@ /* acct_s.c - Send accounting event information to server. * - * Copyright (C) 2010, Pawel Krawczyk <kravietz@ceti.pl> and + * Copyright (C) 2010, Pawel Krawczyk <pawel.krawczyk@hush.com> and * Jeroen Nijhof <jeroen@nijhofnet.nl> * * This program is free software; you can redistribute it and/or modify @@ -23,129 +23,138 @@ #include "libtac.h" #include "xalloc.h" +/* + * return value: + * 0 : success + * < 0 : error status code, see LIBTAC_STATUS_... + * LIBTAC_STATUS_WRITE_ERR + * LIBTAC_STATUS_WRITE_TIMEOUT (pending impl) + * LIBTAC_STATUS_ASSEMBLY_ERR (pending impl) + */ int tac_account_send(int fd, int type, const char *user, char *tty, - struct tac_attrib *attr) { - HDR *th; - struct acct tb; - u_char user_len, port_len; - struct tac_attrib *a; - int i = 0; /* arg count */ - int pkt_len = 0; - int pktl = 0; - int w; /* write count */ - u_char *pkt; - /* u_char *pktp; */ /* obsolute */ - int ret = 0; - - th=_tac_req_header(TAC_PLUS_ACCT); - - /* set header options */ - th->version=TAC_PLUS_VER_0; - th->encryption=tac_encryption ? TAC_PLUS_ENCRYPTED : TAC_PLUS_CLEAR; - - TACDEBUG((LOG_DEBUG, "%s: user '%s', tty '%s', encrypt: %s, type: %s", \ - __FUNCTION__, user, tty, \ - (tac_encryption) ? "yes" : "no", \ - (type == TAC_PLUS_ACCT_FLAG_START) ? "START" : "STOP")) - - user_len=(u_char) strlen(user); - port_len=(u_char) strlen(tty); - - tb.flags=(u_char) type; - tb.authen_method=AUTHEN_METH_TACACSPLUS; - tb.priv_lvl=TAC_PLUS_PRIV_LVL_MIN; - if(strcmp(tac_login,"chap") == 0) { - tb.authen_type=TAC_PLUS_AUTHEN_TYPE_CHAP; - } else if(strcmp(tac_login,"login") == 0) { - tb.authen_type=TAC_PLUS_AUTHEN_TYPE_ASCII; - } else { - tb.authen_type=TAC_PLUS_AUTHEN_TYPE_PAP; - } - tb.authen_service=TAC_PLUS_AUTHEN_SVC_PPP; - tb.user_len=user_len; - tb.port_len=port_len; - tb.rem_addr_len=0; - - /* allocate packet */ - pkt=(u_char *) xcalloc(1, TAC_ACCT_REQ_FIXED_FIELDS_SIZE); - pkt_len=sizeof(tb); - - /* fill attribute length fields */ - a = attr; - while(a) { - - pktl = pkt_len; - pkt_len += sizeof(a->attr_len); - pkt = xrealloc(pkt, pkt_len); - - /* see comments in author_s.c - pktp=pkt + pkt_len; - pkt_len += sizeof(a->attr_len); - pkt = xrealloc(pkt, pkt_len); - */ - - bcopy(&a->attr_len, pkt + pktl, sizeof(a->attr_len)); - i++; - - a = a->next; - } - - /* fill the arg count field and add the fixed fields to packet */ - tb.arg_cnt = i; - bcopy(&tb, pkt, TAC_ACCT_REQ_FIXED_FIELDS_SIZE); - - /* + char *rem_addr, struct tac_attrib *attr) { + + HDR *th; + struct acct tb; + u_char user_len, port_len, rem_addr_len; + struct tac_attrib *a; + int i = 0; /* arg count */ + int pkt_len = 0; + int pktl = 0; + int w; /* write count */ + u_char *pkt=NULL; + /* u_char *pktp; */ /* obsolute */ + int ret = 0; + + th=_tac_req_header(TAC_PLUS_ACCT, 0); + + /* set header options */ + th->version=TAC_PLUS_VER_0; + th->encryption=tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG; + + TACDEBUG((LOG_DEBUG, "%s: user '%s', tty '%s', rem_addr '%s', encrypt: %s, type: %s", \ + __FUNCTION__, user, tty, rem_addr, \ + (tac_encryption) ? "yes" : "no", \ + (type == TAC_PLUS_ACCT_FLAG_START) ? "START" : "STOP")) + + user_len=(u_char) strlen(user); + port_len=(u_char) strlen(tty); + rem_addr_len=(u_char) strlen(rem_addr); + + tb.flags=(u_char) type; + tb.authen_method=tac_authen_method; + tb.priv_lvl=tac_priv_lvl; + if(strcmp(tac_login,"chap") == 0) { + tb.authen_type=TAC_PLUS_AUTHEN_TYPE_CHAP; + } else if(strcmp(tac_login,"login") == 0) { + tb.authen_type=TAC_PLUS_AUTHEN_TYPE_ASCII; + } else { + tb.authen_type=TAC_PLUS_AUTHEN_TYPE_PAP; + } + tb.authen_service=tac_authen_service; + tb.user_len=user_len; + tb.port_len=port_len; + tb.rem_addr_len=rem_addr_len; + + /* allocate packet */ + pkt=(u_char *) xcalloc(1, TAC_ACCT_REQ_FIXED_FIELDS_SIZE); + pkt_len=sizeof(tb); + + /* fill attribute length fields */ + a = attr; + while(a) { + pktl = pkt_len; + pkt_len += sizeof(a->attr_len); + pkt = (u_char*) xrealloc(pkt, pkt_len); + + /* see comments in author_s.c + pktp=pkt + pkt_len; + pkt_len += sizeof(a->attr_len); + pkt = xrealloc(pkt, pkt_len); + */ + + bcopy(&a->attr_len, pkt + pktl, sizeof(a->attr_len)); + i++; + + a = a->next; + } + + /* fill the arg count field and add the fixed fields to packet */ + tb.arg_cnt = i; + bcopy(&tb, pkt, TAC_ACCT_REQ_FIXED_FIELDS_SIZE); + + /* #define PUTATTR(data, len) \ - pktp = pkt + pkt_len; \ - pkt_len += len; \ - pkt = xrealloc(pkt, pkt_len); \ - bcopy(data, pktp, len); -*/ + pktp = pkt + pkt_len; \ + pkt_len += len; \ + pkt = xrealloc(pkt, pkt_len); \ + bcopy(data, pktp, len); + */ #define PUTATTR(data, len) \ - pktl = pkt_len; \ - pkt_len += len; \ - pkt = xrealloc(pkt, pkt_len); \ - bcopy(data, pkt + pktl, len); - - /* fill user and port fields */ - PUTATTR(user, user_len) - PUTATTR(tty, port_len) - - /* fill attributes */ - a = attr; - while(a) { - PUTATTR(a->attr, a->attr_len) - - a = a->next; - } - - /* finished building packet, fill len_from_header in header */ - th->datalength = htonl(pkt_len); - - /* write header */ - w=write(fd, th, TAC_PLUS_HDR_SIZE); - - if(w < TAC_PLUS_HDR_SIZE) { - syslog(LOG_ERR, "%s: acct hdr send failed: wrote %d of %d", - __FUNCTION__, w, - TAC_PLUS_HDR_SIZE); - ret = -1; - } - - /* encrypt packet body */ - _tac_crypt(pkt, th, pkt_len); - - /* write body */ - w=write(fd, pkt, pkt_len); - if(w < pkt_len) { - syslog(LOG_ERR, "%s: acct body send failed: wrote %d of %d", - __FUNCTION__, w, - pkt_len); - ret = -1; - } - - free(pkt); - free(th); - - return(ret); + pktl = pkt_len; \ + pkt_len += len; \ + pkt = (u_char*) xrealloc(pkt, pkt_len); \ + bcopy(data, pkt + pktl, len); + + /* fill user and port fields */ + PUTATTR(user, user_len) + PUTATTR(tty, port_len) + PUTATTR(rem_addr, rem_addr_len) + + /* fill attributes */ + a = attr; + while(a) { + PUTATTR(a->attr, a->attr_len) + a = a->next; + } + + /* finished building packet, fill len_from_header in header */ + th->datalength = htonl(pkt_len); + + /* write header */ + w=write(fd, th, TAC_PLUS_HDR_SIZE); + + if(w < TAC_PLUS_HDR_SIZE) { + TACSYSLOG((LOG_ERR, "%s: short write on header, wrote %d of %d: %m",\ + __FUNCTION__, w, TAC_PLUS_HDR_SIZE)) + ret = LIBTAC_STATUS_WRITE_ERR; + goto AcctExit; + } + + /* encrypt packet body */ + _tac_crypt(pkt, th, pkt_len); + + /* write body */ + w=write(fd, pkt, pkt_len); + if(w < pkt_len) { + TACSYSLOG((LOG_ERR, "%s: short write on body, wrote %d of %d: %m",\ + __FUNCTION__, w, pkt_len)) + ret = LIBTAC_STATUS_WRITE_ERR; + } + +AcctExit: + free(pkt); + free(th); + TACDEBUG((LOG_DEBUG, "%s: exit status=%d", __FUNCTION__, ret)) + return(ret); } |