Lines Matching +full:h +full:- +full:- +full:- +full:- +full:-

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/time.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
35 #include <assert.h>
36 #include <ctype.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <md5.h>
40 #include <netdb.h>
41 #include <stdarg.h>
42 #include <stddef.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
48 #include <security/pam_appl.h>
49 #include <security/openpam.h>
51 #include "taclib_private.h"
86 * length into the 8-bit field referenced by "fld". Returns 0 on
87 * success, or -1 on failure.
93 add_str_8(struct tac_handle *h, u_int8_t *fld, struct tac_str *cs) in add_str_8() argument
97 if (add_str_16(h, &len, cs) == -1) in add_str_8()
98 return -1; in add_str_8()
101 generr(h, "Field too long"); in add_str_8()
102 return -1; in add_str_8()
110 * length into the 16-bit field (network byte order) referenced by
111 * "fld". Returns 0 on success, or -1 on failure.
117 add_str_16(struct tac_handle *h, u_int16_t *fld, struct tac_str *cs) in add_str_16() argument
121 len = cs->len; in add_str_16()
122 if (cs->data == NULL) in add_str_16()
128 generr(h, "Field too long"); in add_str_16()
129 return -1; in add_str_16()
131 offset = ntohl(h->request.length); in add_str_16()
133 generr(h, "Message too long"); in add_str_16()
134 return -1; in add_str_16()
136 memcpy(h->request.u.body + offset, cs->data, len); in add_str_16()
137 h->request.length = htonl(offset + len); in add_str_16()
186 * authentication methods" in taclib.h) are minor version 0 in protocol_version()
228 close_connection(struct tac_handle *h) in close_connection() argument
230 if (h->fd != -1) { in close_connection()
231 close(h->fd); in close_connection()
232 h->fd = -1; in close_connection()
237 conn_server(struct tac_handle *h) in conn_server() argument
239 struct tac_server *srvp = &h->servers[h->cur_server]; in conn_server()
242 if ((h->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { in conn_server()
243 generr(h, "Cannot create socket: %s", strerror(errno)); in conn_server()
244 return -1; in conn_server()
246 if ((flags = fcntl(h->fd, F_GETFL, 0)) == -1 || in conn_server()
247 fcntl(h->fd, F_SETFL, flags | O_NONBLOCK) == -1) { in conn_server()
248 generr(h, "Cannot set non-blocking mode on socket: %s", in conn_server()
250 close(h->fd); in conn_server()
251 h->fd = -1; in conn_server()
252 return -1; in conn_server()
254 if (connect(h->fd, (struct sockaddr *)&srvp->addr, in conn_server()
255 sizeof srvp->addr) == 0) in conn_server()
268 FD_SET(h->fd, &wfds); in conn_server()
269 tv.tv_sec = srvp->timeout; in conn_server()
271 nfds = select(h->fd + 1, NULL, &wfds, NULL, &tv); in conn_server()
272 if (nfds == -1) { in conn_server()
273 generr(h, "select: %s", strerror(errno)); in conn_server()
274 close(h->fd); in conn_server()
275 h->fd = -1; in conn_server()
276 return -1; in conn_server()
279 generr(h, "connect: timed out"); in conn_server()
280 close(h->fd); in conn_server()
281 h->fd = -1; in conn_server()
282 return -1; in conn_server()
287 if (getpeername(h->fd, &peer, &peerlen) == 0) in conn_server()
291 generr(h, "getpeername: %s", strerror(errno)); in conn_server()
292 close(h->fd); in conn_server()
293 h->fd = -1; in conn_server()
294 return -1; in conn_server()
299 getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &err, &errlen); in conn_server()
302 generr(h, "connect: %s", strerror(errno)); in conn_server()
303 close(h->fd); in conn_server()
304 h->fd = -1; in conn_server()
305 return -1; in conn_server()
312 crypt_msg(struct tac_handle *h, struct tac_msg *msg) in crypt_msg() argument
321 secret = h->servers[h->cur_server].secret; in crypt_msg()
323 msg->flags |= TAC_UNENCRYPTED; in crypt_msg()
324 if (msg->flags & TAC_UNENCRYPTED) in crypt_msg()
327 msg_len = ntohl(msg->length); in crypt_msg()
330 MD5Update(&base_ctx, msg->session_id, sizeof msg->session_id); in crypt_msg()
332 MD5Update(&base_ctx, &msg->version, sizeof msg->version); in crypt_msg()
333 MD5Update(&base_ctx, &msg->seq_no, sizeof msg->seq_no); in crypt_msg()
342 if ((chunk_len = msg_len - chunk) > sizeof md5) in crypt_msg()
345 msg->u.body[chunk + i] ^= md5[i]; in crypt_msg()
354 * The copy is null-terminated. If "len" is non-NULL, the length of
360 dup_str(struct tac_handle *h, const struct tac_str *ss, size_t *len) in dup_str() argument
364 if ((p = (unsigned char *)xmalloc(h, ss->len + 1)) == NULL) in dup_str()
366 if (ss->data != NULL && ss->len != 0) in dup_str()
367 memcpy(p, ss->data, ss->len); in dup_str()
368 p[ss->len] = '\0'; in dup_str()
370 *len = ss->len; in dup_str()
375 establish_connection(struct tac_handle *h) in establish_connection() argument
379 if (h->fd >= 0) /* Already connected. */ in establish_connection()
381 if (h->num_servers == 0) { in establish_connection()
382 generr(h, "No TACACS+ servers specified"); in establish_connection()
383 return -1; in establish_connection()
386 * Try the servers round-robin. We begin with the one that in establish_connection()
390 for (i = 0; i < h->num_servers; i++) { in establish_connection()
391 if (conn_server(h) == 0) { in establish_connection()
392 h->single_connect = (h->servers[h->cur_server].flags & in establish_connection()
396 if (++h->cur_server >= h->num_servers) /* Wrap around */ in establish_connection()
397 h->cur_server = 0; in establish_connection()
400 return -1; in establish_connection()
409 if (cs->data != NULL) { in free_str()
410 memset_s(cs->data, cs->len, 0, cs->len); in free_str()
411 free(cs->data); in free_str()
412 cs->data = NULL; in free_str()
413 cs->len = 0; in free_str()
418 generr(struct tac_handle *h, const char *format, ...) in generr() argument
423 vsnprintf(h->errmsg, ERRSIZE, format, ap); in generr()
433 msg->session_id[0] = r >> 8; in gen_session_id()
434 msg->session_id[1] = r; in gen_session_id()
436 msg->session_id[2] = r >> 8; in gen_session_id()
437 msg->session_id[3] = r; in gen_session_id()
442 * Returns 0 on success, -1 on failure.
445 get_srvr_end(struct tac_handle *h) in get_srvr_end() argument
449 len = ntohl(h->response.length); in get_srvr_end()
451 if (h->srvr_pos != len) { in get_srvr_end()
452 generr(h, "Invalid length field in response " in get_srvr_end()
454 h->srvr_pos, len); in get_srvr_end()
455 return -1; in get_srvr_end()
461 get_str(struct tac_handle *h, const char *field, in get_str() argument
464 if (h->srvr_pos + len > ntohl(h->response.length)) { in get_str()
465 generr(h, "Invalid length field in %s response from server " in get_str()
466 "(%lu > %lu)", field, (u_long)(h->srvr_pos + len), in get_str()
467 (u_long)ntohl(h->response.length)); in get_str()
468 return -1; in get_str()
470 ss->data = len != 0 ? h->response.u.body + h->srvr_pos : NULL; in get_str()
471 ss->len = len; in get_str()
472 h->srvr_pos += len; in get_str()
479 cs->data = NULL; in init_str()
480 cs->len = 0; in init_str()
484 read_timed(struct tac_handle *h, void *buf, size_t len, in read_timed() argument
493 n = read(h->fd, ptr, len); in read_timed()
494 if (n == -1) { in read_timed()
499 generr(h, "Network read error: %s", in read_timed()
501 return -1; in read_timed()
511 FD_SET(h->fd, &rfds); in read_timed()
513 select(h->fd + 1, &rfds, NULL, NULL, &tv); in read_timed()
514 if (nfds == -1) { in read_timed()
515 generr(h, "select: %s", in read_timed()
517 return -1; in read_timed()
522 generr(h, "Network read timed out"); in read_timed()
523 return -1; in read_timed()
526 generr(h, "unexpected EOF from server"); in read_timed()
527 return -1; in read_timed()
530 len -= n; in read_timed()
538 * success, or -1 on failure.
541 recv_msg(struct tac_handle *h) in recv_msg() argument
547 msg = &h->response; in recv_msg()
549 deadline.tv_sec += h->servers[h->cur_server].timeout; in recv_msg()
552 if (read_timed(h, msg, HDRSIZE, &deadline) == -1) in recv_msg()
553 return -1; in recv_msg()
554 if (memcmp(msg->session_id, h->request.session_id, in recv_msg()
555 sizeof msg->session_id) != 0) { in recv_msg()
556 generr(h, "Invalid session ID in received message"); in recv_msg()
557 return -1; in recv_msg()
559 if (msg->type != h->request.type) { in recv_msg()
560 generr(h, "Invalid type in received message" in recv_msg()
562 msg->type, h->request.type); in recv_msg()
563 return -1; in recv_msg()
565 len = ntohl(msg->length); in recv_msg()
567 generr(h, "Received message too large (%u > %u)", in recv_msg()
569 return -1; in recv_msg()
571 if (msg->seq_no != ++h->last_seq_no) { in recv_msg()
572 generr(h, "Invalid sequence number in received message" in recv_msg()
574 msg->seq_no, h->last_seq_no); in recv_msg()
575 return -1; in recv_msg()
579 if (read_timed(h, msg->u.body, len, &deadline) == -1) in recv_msg()
580 return -1; in recv_msg()
583 crypt_msg(h, msg); in recv_msg()
586 * Turn off single-connection mode if the server isn't amenable in recv_msg()
589 if (!(msg->flags & TAC_SINGLE_CONNECT)) in recv_msg()
590 h->single_connect = 0; in recv_msg()
595 save_str(struct tac_handle *h, struct tac_str *cs, const void *data, in save_str() argument
600 if ((cs->data = xmalloc(h, len)) == NULL) in save_str()
601 return -1; in save_str()
602 cs->len = len; in save_str()
603 memcpy(cs->data, data, len); in save_str()
610 * or -1 on failure.
613 send_msg(struct tac_handle *h) in send_msg() argument
620 if (h->last_seq_no & 1) { in send_msg()
621 generr(h, "Attempt to send message out of sequence"); in send_msg()
622 return -1; in send_msg()
625 if (establish_connection(h) == -1) in send_msg()
626 return -1; in send_msg()
628 msg = &h->request; in send_msg()
629 msg->seq_no = ++h->last_seq_no; in send_msg()
630 if (msg->seq_no == 1) in send_msg()
632 crypt_msg(h, msg); in send_msg()
634 if (h->single_connect) in send_msg()
635 msg->flags |= TAC_SINGLE_CONNECT; in send_msg()
637 msg->flags &= ~TAC_SINGLE_CONNECT; in send_msg()
639 deadline.tv_sec += h->servers[h->cur_server].timeout; in send_msg()
640 len = HDRSIZE + ntohl(msg->length); in send_msg()
645 n = write(h->fd, ptr, len); in send_msg()
646 if (n == -1) { in send_msg()
651 generr(h, "Network write error: %s", in send_msg()
653 return -1; in send_msg()
663 FD_SET(h->fd, &wfds); in send_msg()
665 select(h->fd + 1, NULL, &wfds, NULL, &tv); in send_msg()
666 if (nfds == -1) { in send_msg()
667 generr(h, "select: %s", in send_msg()
669 return -1; in send_msg()
674 generr(h, "Network write timed out"); in send_msg()
675 return -1; in send_msg()
679 len -= n; in send_msg()
686 tac_add_server_av(struct tac_handle *h, const char *host, int port, in tac_add_server_av() argument
694 if (h->num_servers >= MAXSERVERS) { in tac_add_server_av()
695 generr(h, "Too many TACACS+ servers specified"); in tac_add_server_av()
696 return -1; in tac_add_server_av()
698 srvp = &h->servers[h->num_servers]; in tac_add_server_av()
700 memset(&srvp->addr, 0, sizeof srvp->addr); in tac_add_server_av()
701 srvp->addr.sin_len = sizeof srvp->addr; in tac_add_server_av()
702 srvp->addr.sin_family = AF_INET; in tac_add_server_av()
703 if (!inet_aton(host, &srvp->addr.sin_addr)) { in tac_add_server_av()
707 generr(h, "%s: host not found", host); in tac_add_server_av()
708 return -1; in tac_add_server_av()
710 memcpy(&srvp->addr.sin_addr, hent->h_addr, in tac_add_server_av()
711 sizeof srvp->addr.sin_addr); in tac_add_server_av()
713 srvp->addr.sin_port = htons(port != 0 ? port : TACPLUS_PORT); in tac_add_server_av()
714 if ((srvp->secret = xstrdup(h, secret)) == NULL) in tac_add_server_av()
715 return -1; in tac_add_server_av()
716 srvp->timeout = timeout; in tac_add_server_av()
717 srvp->flags = flags; in tac_add_server_av()
718 srvp->navs = 0; in tac_add_server_av()
721 generr(h, "too many AV pairs"); in tac_add_server_av()
727 generr(h, "invalid AV pair %d", i); in tac_add_server_av()
732 if ((srvp->avs[i].data = xstrdup(h, avs[i])) == NULL) in tac_add_server_av()
734 srvp->avs[i].len = len; in tac_add_server_av()
735 srvp->navs++; in tac_add_server_av()
737 h->num_servers++; in tac_add_server_av()
740 memset_s(srvp->secret, strlen(srvp->secret), 0, strlen(srvp->secret)); in tac_add_server_av()
741 free(srvp->secret); in tac_add_server_av()
742 srvp->secret = NULL; in tac_add_server_av()
743 for (i = 0; i < srvp->navs; i++) { in tac_add_server_av()
744 free(srvp->avs[i].data); in tac_add_server_av()
745 srvp->avs[i].data = NULL; in tac_add_server_av()
746 srvp->avs[i].len = 0; in tac_add_server_av()
748 return -1; in tac_add_server_av()
752 tac_add_server(struct tac_handle *h, const char *host, int port, in tac_add_server() argument
757 return tac_add_server_av(h, host, port, secret, timeout, flags, avs); in tac_add_server()
761 tac_close(struct tac_handle *h) in tac_close() argument
765 if (h->fd != -1) in tac_close()
766 close(h->fd); in tac_close()
767 for (srv = 0; srv < h->num_servers; srv++) { in tac_close()
768 memset(h->servers[srv].secret, 0, in tac_close()
769 strlen(h->servers[srv].secret)); in tac_close()
770 free(h->servers[srv].secret); in tac_close()
772 free_str(&h->user); in tac_close()
773 free_str(&h->port); in tac_close()
774 free_str(&h->rem_addr); in tac_close()
775 free_str(&h->data); in tac_close()
776 free_str(&h->user_msg); in tac_close()
778 free_str(&(h->avs[i])); in tac_close()
781 memset(h, 0, sizeof(struct tac_handle)); in tac_close()
782 free(h); in tac_close()
789 while (nfields-- > 0) in freev()
796 tac_config(struct tac_handle *h, const char *path) in tac_config() argument
806 generr(h, "Cannot open \"%s\": %s", path, strerror(errno)); in tac_config()
807 return -1; in tac_config()
828 generr(h, "%s:%d: missing shared secret", path, in tac_config()
830 retval = -1; in tac_config()
843 generr(h, "%s:%d: invalid port", path, in tac_config()
845 retval = -1; in tac_config()
856 generr(h, "%s:%d: invalid timeout", path, in tac_config()
858 retval = -1; in tac_config()
866 strcmp(fields[i], "single-connection") == 0) { in tac_config()
870 if (tac_add_server_av(h, host, port, secret, timeout, in tac_config()
871 options, (const char *const *)(fields + i)) == -1) { in tac_config()
874 strcpy(msg, h->errmsg); in tac_config()
875 generr(h, "%s:%d: %s", path, linenum, msg); in tac_config()
876 retval = -1; in tac_config()
888 tac_create_authen(struct tac_handle *h, int action, int type, int service) in tac_create_authen() argument
892 create_msg(h, TAC_AUTHEN, action, type); in tac_create_authen()
894 as = &h->request.u.authen_start; in tac_create_authen()
895 as->action = action; in tac_create_authen()
896 as->priv_lvl = TAC_PRIV_LVL_USER; in tac_create_authen()
897 as->authen_type = type; in tac_create_authen()
898 as->service = service; in tac_create_authen()
904 tac_create_author(struct tac_handle *h, int method, int type, int service) in tac_create_author() argument
908 create_msg(h, TAC_AUTHOR, method, type); in tac_create_author()
910 areq = &h->request.u.author_request; in tac_create_author()
911 areq->authen_meth = method; in tac_create_author()
912 areq->priv_lvl = TAC_PRIV_LVL_USER; in tac_create_author()
913 areq->authen_type = type; in tac_create_author()
914 areq->service = service; in tac_create_author()
920 tac_create_acct(struct tac_handle *h, int acct, int action, int type, int service) in tac_create_acct() argument
924 create_msg(h, TAC_ACCT, action, type); in tac_create_acct()
926 as = &h->request.u.acct_start; in tac_create_acct()
927 as->action = acct; in tac_create_acct()
928 as->authen_action = action; in tac_create_acct()
929 as->priv_lvl = TAC_PRIV_LVL_USER; in tac_create_acct()
930 as->authen_type = type; in tac_create_acct()
931 as->authen_service = service; in tac_create_acct()
937 create_msg(struct tac_handle *h, int msg_type, int var, int type) in create_msg() argument
942 h->last_seq_no = 0; in create_msg()
944 msg = &h->request; in create_msg()
945 msg->type = msg_type; in create_msg()
946 msg->version = protocol_version(msg_type, var, type); in create_msg()
947 msg->flags = 0; /* encrypted packet body */ in create_msg()
949 free_str(&h->user); in create_msg()
950 free_str(&h->port); in create_msg()
951 free_str(&h->rem_addr); in create_msg()
952 free_str(&h->data); in create_msg()
953 free_str(&h->user_msg); in create_msg()
956 free_str(&(h->avs[i])); in create_msg()
960 tac_get_data(struct tac_handle *h, size_t *len) in tac_get_data() argument
962 return dup_str(h, &h->srvr_data, len); in tac_get_data()
966 tac_get_msg(struct tac_handle *h) in tac_get_msg() argument
968 return dup_str(h, &h->srvr_msg, NULL); in tac_get_msg()
980 struct tac_handle *h; in tac_open() local
982 h = (struct tac_handle *)malloc(sizeof(struct tac_handle)); in tac_open()
983 if (h != NULL) { in tac_open()
984 h->fd = -1; in tac_open()
985 h->num_servers = 0; in tac_open()
986 h->cur_server = 0; in tac_open()
987 h->errmsg[0] = '\0'; in tac_open()
988 init_str(&h->user); in tac_open()
989 init_str(&h->port); in tac_open()
990 init_str(&h->rem_addr); in tac_open()
991 init_str(&h->data); in tac_open()
992 init_str(&h->user_msg); in tac_open()
994 init_str(&(h->avs[i])); in tac_open()
995 init_str(&(h->srvr_avs[i])); in tac_open()
997 init_str(&h->srvr_msg); in tac_open()
998 init_str(&h->srvr_data); in tac_open()
1000 return h; in tac_open()
1004 tac_send_authen(struct tac_handle *h) in tac_send_authen() argument
1008 if (h->num_servers == 0) in tac_send_authen()
1009 return -1; in tac_send_authen()
1011 if (h->last_seq_no == 0) { /* Authentication START packet */ in tac_send_authen()
1014 as = &h->request.u.authen_start; in tac_send_authen()
1015 h->request.length = in tac_send_authen()
1017 if (add_str_8(h, &as->user_len, &h->user) == -1 || in tac_send_authen()
1018 add_str_8(h, &as->port_len, &h->port) == -1 || in tac_send_authen()
1019 add_str_8(h, &as->rem_addr_len, &h->rem_addr) == -1 || in tac_send_authen()
1020 add_str_8(h, &as->data_len, &h->data) == -1) in tac_send_authen()
1021 return -1; in tac_send_authen()
1025 ac = &h->request.u.authen_cont; in tac_send_authen()
1026 ac->flags = 0; in tac_send_authen()
1027 h->request.length = in tac_send_authen()
1029 if (add_str_16(h, &ac->user_msg_len, &h->user_msg) == -1 || in tac_send_authen()
1030 add_str_16(h, &ac->data_len, &h->data) == -1) in tac_send_authen()
1031 return -1; in tac_send_authen()
1035 if (send_msg(h) == -1 || recv_msg(h) == -1) in tac_send_authen()
1036 return -1; in tac_send_authen()
1039 ar = &h->response.u.authen_reply; in tac_send_authen()
1040 h->srvr_pos = offsetof(struct tac_authen_reply, rest[0]); in tac_send_authen()
1041 if (get_str(h, "msg", &h->srvr_msg, ntohs(ar->msg_len)) == -1 || in tac_send_authen()
1042 get_str(h, "data", &h->srvr_data, ntohs(ar->data_len)) == -1 || in tac_send_authen()
1043 get_srvr_end(h) == -1) in tac_send_authen()
1044 return -1; in tac_send_authen()
1046 if (!h->single_connect && in tac_send_authen()
1047 ar->status != TAC_AUTHEN_STATUS_GETDATA && in tac_send_authen()
1048 ar->status != TAC_AUTHEN_STATUS_GETUSER && in tac_send_authen()
1049 ar->status != TAC_AUTHEN_STATUS_GETPASS) in tac_send_authen()
1050 close_connection(h); in tac_send_authen()
1052 return ar->flags << 8 | ar->status; in tac_send_authen()
1056 tac_send_author(struct tac_handle *h) in tac_send_author() argument
1060 struct tac_author_request *areq = &h->request.u.author_request; in tac_send_author()
1061 struct tac_author_response *ares = &h->response.u.author_response; in tac_send_author()
1064 h->request.length = in tac_send_author()
1068 for (areq->av_cnt=0, i=0; i<MAXAVPAIRS; i++) in tac_send_author()
1069 if (h->avs[i].len && h->avs[i].data) in tac_send_author()
1070 areq->av_cnt++; in tac_send_author()
1076 h->request.length = ntohl(htonl(h->request.length) + areq->av_cnt); in tac_send_author()
1078 /* Now add the string arguments from 'h' */ in tac_send_author()
1079 if (add_str_8(h, &areq->user_len, &h->user) == -1 || in tac_send_author()
1080 add_str_8(h, &areq->port_len, &h->port) == -1 || in tac_send_author()
1081 add_str_8(h, &areq->rem_addr_len, &h->rem_addr) == -1) in tac_send_author()
1082 return -1; in tac_send_author()
1084 /* Add each AV pair, the size of each placed in areq->rest[current] */ in tac_send_author()
1086 if (h->avs[i].len && h->avs[i].data) { in tac_send_author()
1087 if (add_str_8(h, &areq->rest[current++], in tac_send_author()
1088 &(h->avs[i])) == -1) in tac_send_author()
1089 return -1; in tac_send_author()
1094 if (send_msg(h) == -1 || recv_msg(h) == -1) in tac_send_author()
1095 return -1; in tac_send_author()
1096 srvp = &h->servers[h->cur_server]; in tac_send_author()
1099 h->srvr_pos = offsetof(struct tac_author_response, rest[0]) + in tac_send_author()
1100 ares->av_cnt; in tac_send_author()
1103 if (get_str(h, "msg", &h->srvr_msg, ntohs(ares->msg_len)) == -1 || in tac_send_author()
1104 get_str(h, "data", &h->srvr_data, ntohs(ares->data_len)) ==-1) in tac_send_author()
1105 return -1; in tac_send_author()
1108 clear_srvr_avs(h); in tac_send_author()
1109 for (i=0; i<ares->av_cnt; i++) { in tac_send_author()
1110 snprintf(dbgstr, sizeof dbgstr, "av-pair-%d", i); in tac_send_author()
1111 if (get_str(h, dbgstr, &(h->srvr_avs[i]), in tac_send_author()
1112 ares->rest[i]) == -1) in tac_send_author()
1113 return -1; in tac_send_author()
1114 h->srvr_navs++; in tac_send_author()
1118 if (get_srvr_end(h) == -1) in tac_send_author()
1119 return -1; in tac_send_author()
1122 if (!h->single_connect) in tac_send_author()
1123 close_connection(h); in tac_send_author()
1125 return (h->srvr_navs + srvp->navs) << 8 | ares->status; in tac_send_author()
1129 tac_send_acct(struct tac_handle *h) in tac_send_acct() argument
1132 struct tac_acct_start *as = &h->request.u.acct_start; in tac_send_acct()
1133 struct tac_acct_reply *ar = &h->response.u.acct_reply; in tac_send_acct()
1136 as = &h->request.u.acct_start; in tac_send_acct()
1137 h->request.length = htonl(offsetof(struct tac_acct_start, rest[0])); in tac_send_acct()
1138 for (as->av_cnt = 0, i = 0; i < MAXAVPAIRS; i++) in tac_send_acct()
1139 if (h->avs[i].len && h->avs[i].data) in tac_send_acct()
1140 as->av_cnt++; in tac_send_acct()
1141 h->request.length = ntohl(htonl(h->request.length) + as->av_cnt); in tac_send_acct()
1143 if (add_str_8(h, &as->user_len, &h->user) == -1 || in tac_send_acct()
1144 add_str_8(h, &as->port_len, &h->port) == -1 || in tac_send_acct()
1145 add_str_8(h, &as->rem_addr_len, &h->rem_addr) == -1) in tac_send_acct()
1146 return -1; in tac_send_acct()
1149 if (h->avs[i].len && h->avs[i].data) in tac_send_acct()
1150 if (add_str_8(h, &as->rest[current++], &(h->avs[i])) == -1) in tac_send_acct()
1151 return -1; in tac_send_acct()
1154 if (send_msg(h) == -1 || recv_msg(h) == -1) in tac_send_acct()
1155 return -1; in tac_send_acct()
1158 h->srvr_pos = offsetof(struct tac_acct_reply, rest[0]); in tac_send_acct()
1159 if (get_str(h, "msg", &h->srvr_msg, ntohs(ar->msg_len)) == -1 || in tac_send_acct()
1160 get_str(h, "data", &h->srvr_data, ntohs(ar->data_len)) == -1 || in tac_send_acct()
1161 get_srvr_end(h) == -1) in tac_send_acct()
1162 return -1; in tac_send_acct()
1165 if (!h->single_connect) in tac_send_acct()
1166 close_connection(h); in tac_send_acct()
1168 return ar->status; in tac_send_acct()
1172 tac_set_rem_addr(struct tac_handle *h, const char *addr) in tac_set_rem_addr() argument
1174 return save_str(h, &h->rem_addr, addr, addr != NULL ? strlen(addr) : 0); in tac_set_rem_addr()
1178 tac_set_data(struct tac_handle *h, const void *data, size_t data_len) in tac_set_data() argument
1180 return save_str(h, &h->data, data, data_len); in tac_set_data()
1184 tac_set_msg(struct tac_handle *h, const char *msg) in tac_set_msg() argument
1186 return save_str(h, &h->user_msg, msg, msg != NULL ? strlen(msg) : 0); in tac_set_msg()
1190 tac_set_port(struct tac_handle *h, const char *port) in tac_set_port() argument
1192 return save_str(h, &h->port, port, port != NULL ? strlen(port) : 0); in tac_set_port()
1196 tac_set_priv(struct tac_handle *h, int priv) in tac_set_priv() argument
1199 generr(h, "Attempt to set invalid privilege level"); in tac_set_priv()
1200 return -1; in tac_set_priv()
1202 h->request.u.authen_start.priv_lvl = priv; in tac_set_priv()
1207 tac_set_user(struct tac_handle *h, const char *user) in tac_set_user() argument
1209 return save_str(h, &h->user, user, user != NULL ? strlen(user) : 0); in tac_set_user()
1213 tac_set_av(struct tac_handle *h, u_int index, const char *av) in tac_set_av() argument
1216 return -1; in tac_set_av()
1217 return save_str(h, &(h->avs[index]), av, av != NULL ? strlen(av) : 0); in tac_set_av()
1221 tac_get_av(struct tac_handle *h, u_int index) in tac_get_av() argument
1225 if (index < h->srvr_navs) in tac_get_av()
1226 return dup_str(h, &h->srvr_avs[index], NULL); in tac_get_av()
1227 index -= h->srvr_navs; in tac_get_av()
1228 srvp = &h->servers[h->cur_server]; in tac_get_av()
1229 if (index < srvp->navs) in tac_get_av()
1230 return xstrdup(h, srvp->avs[index].data); in tac_get_av()
1235 tac_get_av_value(struct tac_handle *h, const char *attribute) in tac_get_av_value() argument
1242 struct tac_server *srvp = &h->servers[h->cur_server]; in tac_get_av_value()
1247 for (i = 0; i < h->srvr_navs + srvp->navs; i++) { in tac_get_av_value()
1248 if (i < h->srvr_navs) in tac_get_av_value()
1249 candidate = &h->srvr_avs[i]; in tac_get_av_value()
1251 candidate = &srvp->avs[i - h->srvr_navs]; in tac_get_av_value()
1253 if (attr_len < candidate->len && in tac_get_av_value()
1254 strncmp(candidate->data, attribute, attr_len) == 0) { in tac_get_av_value()
1256 ch = candidate->data + attr_len; in tac_get_av_value()
1257 end = candidate->data + candidate->len; in tac_get_av_value()
1274 * h->srvr_avs[0] = "foobie=var1" in tac_get_av_value()
1275 * h->srvr_avs[1] = "foo=var2" in tac_get_av_value()
1279 * 0-length string is returned in order to distinguish in tac_get_av_value()
1284 value.len = end - ch; in tac_get_av_value()
1286 return dup_str(h, &value, NULL); in tac_get_av_value()
1294 tac_clear_avs(struct tac_handle *h) in tac_clear_avs() argument
1298 save_str(h, &(h->avs[i]), NULL, 0); in tac_clear_avs()
1302 clear_srvr_avs(struct tac_handle *h) in clear_srvr_avs() argument
1306 for (i = 0; i < h->srvr_navs; i++) in clear_srvr_avs()
1307 init_str(&(h->srvr_avs[i])); in clear_srvr_avs()
1308 h->srvr_navs = 0; in clear_srvr_avs()
1313 tac_strerror(struct tac_handle *h) in tac_strerror() argument
1315 return h->errmsg; in tac_strerror()
1319 xmalloc(struct tac_handle *h, size_t size) in xmalloc() argument
1324 generr(h, "Out of memory"); in xmalloc()
1329 xstrdup(struct tac_handle *h, const char *s) in xstrdup() argument
1334 generr(h, "Out of memory"); in xstrdup()