Release bumped to "gts4".
[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
21 #include "tac_plus.h"
22
23 #include <stdlib.h>
24 #include <netinet/in.h>         /* for ntohl() */
25
26 #include "author.h"
27 #include "report.h"
28 #include "packet.h"
29 #include "utils.h"
30 #include "do_author.h"
31 #include "main.h"
32 #include "cfgfile.h"
33
34
35 /*
36  *  Come here when we receive an authorization START packet
37  */
38
39 void author TAC_ARGS((u_char *pak));
40
41 void
42 author(pak)
43 u_char *pak;
44 {
45     HDR *hdr;
46     struct author *apak;
47     struct identity identity;
48     struct author_data author_data;
49     u_char *p;
50     u_char *argsizep;
51     char **cmd_argp;
52     int i;
53     unsigned long len;
54
55     if (debug & DEBUG_AUTHOR_FLAG)
56         report(LOG_DEBUG, "Start authorization request");
57
58     hdr = (HDR *)pak;
59     apak = (struct author *) (pak + TAC_PLUS_HDR_SIZE);
60
61     /* Do some sanity checks */
62     if (hdr->seq_no != 1) {
63         send_error_reply(TAC_PLUS_AUTHOR, NULL);
64         return;
65     }
66
67     /* arg counts start here */
68     p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;
69
70     /* Length checks */
71     len = TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;
72     len += apak->user_len + apak->port_len + apak->rem_addr_len + apak->arg_cnt;
73     for (i = 0; i < (int)apak->arg_cnt; i++) {
74         len += p[i];
75     }
76
77     if (len != (unsigned long) ntohl(hdr->datalength)) {
78         send_error_reply(TAC_PLUS_AUTHOR, NULL);
79         return;
80     }
81
82     /* start of variable length data is here */
83     p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;
84
85     /* arg length data starts here */
86     argsizep = p;
87
88     p += apak->arg_cnt;
89
90     bzero(&author_data, sizeof(struct author_data));
91
92     /* The identity structure */
93
94     /* zero out identity struct */
95     bzero(&identity, sizeof(struct identity));
96     identity.username = tac_make_string(p, (int) apak->user_len);
97     p += apak->user_len;
98
99     identity.NAS_name = tac_strdup(session.peer);
100
101     identity.NAS_port = tac_make_string(p, (int)apak->port_len);
102     p += apak->port_len;
103     if (apak->port_len <= 0) {
104         strcpy(session.port, "unknown-port");
105     } else {
106         strcpy(session.port, identity.NAS_port);
107     }
108
109     identity.NAC_address = tac_make_string(p, (int)apak->rem_addr_len);
110     p += apak->rem_addr_len;
111
112     identity.priv_lvl = apak->priv_lvl;
113
114     cfg_request_identity(&identity);
115
116     /* The author_data structure */
117
118     author_data.id = &identity; /* user id */
119
120     /* FIXME: validate these fields */
121     author_data.authen_method = apak->authen_method;
122     author_data.authen_type = apak->authen_type;
123     author_data.service = apak->service;
124     author_data.num_in_args = apak->arg_cnt;
125
126     /* Space for args + NULL */
127     cmd_argp = (char **) tac_malloc(apak->arg_cnt * sizeof(char *));
128
129     /* p  points to the start of args. Step thru them making strings */
130     for (i = 0; i < (int)apak->arg_cnt; i++) {
131         cmd_argp[i] = tac_make_string(p, *argsizep);
132         p += *argsizep++;
133     }
134
135     author_data.input_args = cmd_argp;  /* input command arguments */
136
137     if (do_author(&author_data)) {
138         report(LOG_ERR, "%s: do_author returned an error", session.peer);
139         send_author_reply(AUTHOR_STATUS_ERROR,
140                           author_data.msg,
141                           author_data.admin_msg,
142                           author_data.num_out_args,
143                           author_data.output_args);
144         return;
145     }
146
147     /* Send a reply packet */
148     send_author_reply(author_data.status,
149                       author_data.msg,
150                       author_data.admin_msg,
151                       author_data.num_out_args,
152                       author_data.output_args);
153
154     if (debug)
155         report(LOG_INFO, "authorization query for '%s' %s from %s %s",
156                author_data.id->username  && author_data.id->username[0] ?
157                author_data.id->username : "unknown",
158                author_data.id->NAS_port && author_data.id->NAS_port[0] ?
159                author_data.id->NAS_port : "unknown",
160                session.peer,
161                (author_data.status == AUTHOR_STATUS_PASS_ADD ||
162                 author_data.status == AUTHOR_STATUS_PASS_REPL) ?
163                "accepted" : "rejected");
164
165     /* free the input args */
166     if (author_data.input_args) {
167         for (i = 0; i < author_data.num_in_args; i++)
168             free(author_data.input_args[i]);
169
170         free(author_data.input_args);
171         author_data.input_args = NULL;
172     }
173
174     /* free the output args */
175     if (author_data.output_args) {
176         for (i=0; i < author_data.num_out_args; i++)
177             free(author_data.output_args[i]);
178
179         free(author_data.output_args);
180         author_data.output_args = NULL;
181     }
182
183     if (author_data.msg)
184         free(author_data.msg);
185
186     if (author_data.admin_msg)
187         free(author_data.admin_msg);
188
189     free(identity.username);
190     free(identity.NAS_name);
191     free(identity.NAS_port);
192     free(identity.NAC_address);
193 }