Import of tac_plus.v8.tar.gz: 173206 bytes, md5:
[tac_plus.git] / author.c
1 /* 
2    Copyright (c) 1995-1998 by Cisco systems, Inc.
3
4    Permission to use, copy, modify, and distribute this software for
5    any purpose and without fee is hereby granted, provided that this
6    copyright and permission notice appear on all copies of the
7    software and supporting documentation, the name of Cisco Systems,
8    Inc. not be used in advertising or publicity pertaining to
9    distribution of the program without specific prior permission, and
10    notice be given in supporting documentation that modification,
11    copying and distribution is by permission of Cisco Systems, Inc.
12
13    Cisco Systems, Inc. makes no representations about the suitability
14    of this software for any purpose.  THIS SOFTWARE IS PROVIDED ``AS
15    IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
16    WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17    FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20 #include "tac_plus.h"
21
22 /*
23  *  Come here when we receive an authorization START packet
24  */
25
26 void
27 author(pak)
28 u_char *pak;
29 {
30     HDR *hdr;
31     struct author *apak;
32     struct identity identity;
33     struct author_data author_data;
34     u_char *p;
35     u_char *argsizep;
36     char **cmd_argp;
37     int i, len;
38
39     if (debug & DEBUG_AUTHOR_FLAG)
40         report(LOG_DEBUG, "Start authorization request");
41
42     hdr = (HDR *)pak;
43     apak = (struct author *) (pak + TAC_PLUS_HDR_SIZE);
44
45     /* Do some sanity checks */
46     if (hdr->seq_no != 1) {
47         send_error_reply(TAC_PLUS_AUTHOR, NULL);
48         return;
49     }
50
51     /* arg counts start here */
52     p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;
53
54     /* Length checks */
55     len = TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;
56     len += apak->user_len + apak->port_len + apak->rem_addr_len + apak->arg_cnt;
57     for (i = 0; i < (int)apak->arg_cnt; i++) {
58         len += p[i];
59     }
60
61     if (len != ntohl(hdr->datalength)) {
62         send_error_reply(TAC_PLUS_AUTHOR, NULL);
63         return;
64     }
65
66     /* start of variable length data is here */
67     p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;
68
69     /* arg length data starts here */
70     argsizep = p;
71
72     p += apak->arg_cnt;
73
74     bzero(&author_data, sizeof(struct author_data));
75
76     /* The identity structure */
77
78     /* zero out identity struct */
79     bzero(&identity, sizeof(struct identity));
80     identity.username = tac_make_string(p, (int) apak->user_len);
81     p += apak->user_len;
82
83     identity.NAS_name = tac_strdup(session.peer);
84
85     identity.NAS_port = tac_make_string(p, (int)apak->port_len);
86     p += apak->port_len;
87     if (apak->port_len <= 0) {
88         strcpy(session.port, "unknown-port");
89     } else {
90         strcpy(session.port, identity.NAS_port);
91     }
92
93     identity.NAC_address = tac_make_string(p, (int)apak->rem_addr_len);
94     p += apak->rem_addr_len;
95
96     identity.priv_lvl = apak->priv_lvl;
97
98     /* The author_data structure */
99
100     author_data.id = &identity; /* user id */
101
102     /* FIXME: validate these fields */
103     author_data.authen_method = apak->authen_method;
104     author_data.authen_type = apak->authen_type;
105     author_data.service = apak->service;
106     author_data.num_in_args = apak->arg_cnt;
107
108     /* Space for args + NULL */
109     cmd_argp = (char **) tac_malloc(apak->arg_cnt * sizeof(char *));
110
111     /* p  points to the start of args. Step thru them making strings */
112     for (i = 0; i < (int)apak->arg_cnt; i++) {
113         cmd_argp[i] = tac_make_string(p, *argsizep);
114         p += *argsizep++;
115     }
116
117     author_data.input_args = cmd_argp;  /* input command arguments */
118
119     if (do_author(&author_data)) {
120         report(LOG_ERR, "%s: do_author returned an error", session.peer);
121         send_author_reply(AUTHOR_STATUS_ERROR,
122                           author_data.msg,
123                           author_data.admin_msg,
124                           author_data.num_out_args,
125                           author_data.output_args);
126         return;
127     }
128
129     /* Send a reply packet */
130     send_author_reply(author_data.status,
131                       author_data.msg,
132                       author_data.admin_msg,
133                       author_data.num_out_args,
134                       author_data.output_args);
135
136     if (debug)
137         report(LOG_INFO, "authorization query for '%s' %s from %s %s",
138                author_data.id->username  && author_data.id->username[0] ?
139                author_data.id->username : "unknown",
140                author_data.id->NAS_port && author_data.id->NAS_port[0] ?
141                author_data.id->NAS_port : "unknown",
142                session.peer,
143                (author_data.status == AUTHOR_STATUS_PASS_ADD ||
144                 author_data.status == AUTHOR_STATUS_PASS_REPL) ?
145                "accepted" : "rejected");
146
147     /* free the input args */
148     if (author_data.input_args) {
149         for (i = 0; i < author_data.num_in_args; i++)
150             free(author_data.input_args[i]);
151         
152         free(author_data.input_args);
153         author_data.input_args = NULL;
154     }
155
156     /* free the output args */
157     if (author_data.output_args) {
158         for (i=0; i < author_data.num_out_args; i++)
159             free(author_data.output_args[i]);
160
161         free(author_data.output_args);
162         author_data.output_args = NULL;
163     }
164
165     if (author_data.msg)
166         free(author_data.msg);
167
168     if (author_data.admin_msg)
169         free(author_data.admin_msg);
170
171     free(identity.username);
172     free(identity.NAS_name);
173     free(identity.NAS_port);
174     free(identity.NAC_address);
175 }