2 * session.c session management
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * Copyright 2000 The FreeRADIUS server project
38 #ifdef HAVE_NETINET_IN_H
39 #include <netinet/in.h>
43 #include "rad_assert.h"
46 /* End a session by faking a Stop packet to all accounting modules */
47 int session_zap(REQUEST *request, uint32_t nasaddr, unsigned int port,
49 const char *sessionid, uint32_t cliaddr, char proto)
52 VALUE_PAIR *vp, *userpair;
55 stopreq = request_alloc_fake(request);
56 stopreq->packet->code = PW_ACCOUNTING_REQUEST; /* just to be safe */
57 rad_assert(stopreq != NULL);
59 /* Hold your breath */
60 #define PAIR(n,v,t,e) do { \
61 if(!(vp = paircreate(n, t))) { \
62 radlog(L_ERR|L_CONS, "no memory"); \
63 pairfree(&(stopreq->packet->vps)); \
67 pairadd(&(stopreq->packet->vps), vp); \
69 #define INTPAIR(n,v) PAIR(n,v,PW_TYPE_INTEGER,lvalue)
70 #define IPPAIR(n,v) PAIR(n,v,PW_TYPE_IPADDR,lvalue)
71 #define STRINGPAIR(n,v) do { \
72 if(!(vp = paircreate(n, PW_TYPE_STRING))) { \
73 radlog(L_ERR|L_CONS, "no memory"); \
74 pairfree(&(stopreq->packet->vps)); \
77 strNcpy((char *)vp->strvalue, v, sizeof vp->strvalue); \
78 vp->length = strlen(v); \
79 pairadd(&(stopreq->packet->vps), vp); \
82 INTPAIR(PW_ACCT_STATUS_TYPE, PW_STATUS_STOP);
83 IPPAIR(PW_NAS_IP_ADDRESS, nasaddr);
84 INTPAIR(PW_ACCT_DELAY_TIME, 0);
85 STRINGPAIR(PW_USER_NAME, user);
87 INTPAIR(PW_NAS_PORT, port);
88 STRINGPAIR(PW_ACCT_SESSION_ID, sessionid);
90 INTPAIR(PW_SERVICE_TYPE, PW_FRAMED_USER);
91 INTPAIR(PW_FRAMED_PROTOCOL, PW_PPP);
92 } else if(proto == 'S') {
93 INTPAIR(PW_SERVICE_TYPE, PW_FRAMED_USER);
94 INTPAIR(PW_FRAMED_PROTOCOL, PW_SLIP);
96 INTPAIR(PW_SERVICE_TYPE, PW_LOGIN_USER); /* A guess, really */
99 IPPAIR(PW_FRAMED_IP_ADDRESS, cliaddr);
100 INTPAIR(PW_ACCT_SESSION_TIME, 0);
101 INTPAIR(PW_ACCT_INPUT_OCTETS, 0);
102 INTPAIR(PW_ACCT_OUTPUT_OCTETS, 0);
103 INTPAIR(PW_ACCT_INPUT_PACKETS, 0);
104 INTPAIR(PW_ACCT_OUTPUT_PACKETS, 0);
106 stopreq->username = userpair;
107 stopreq->password = NULL;
109 ret = rad_accounting(stopreq);
112 * We've got to clean it up by hand, because no one else will.
114 request_free(&stopreq);
121 * Check one terminal server to see if a user is logged in.
123 int rad_check_ts(uint32_t nasaddr, unsigned int portnum, const char *user,
124 const char *session_id)
126 pid_t pid, child_pid;
136 cl = client_find(nasaddr);
139 * Unknown NAS, so trusting radutmp.
141 DEBUG2("checkrad: Unknown NAS %s, not checking",
142 ip_ntoa(address, nasaddr));
147 * No nastype, or nas type 'other', trust radutmp.
149 if ((cl->nastype[0] == '\0') ||
150 (strcmp(cl->nastype, "other") == 0)) {
151 DEBUG2("checkrad: No NAS type, or type \"other\" not checking");
158 if ((pid = rad_fork(1)) < 0) { /* do wait for the fork'd result */
159 radlog(L_ERR, "Accounting: Failed in fork(): Cannot run checkrad\n");
167 * Parent - Wait for checkrad to terminate.
168 * We timeout in 10 seconds.
171 for (n = 0; n < 10; n++) {
173 child_pid = rad_waitpid(pid, &status, WNOHANG);
174 if ((child_pid < 0) || (child_pid == pid)) {
181 * It's taking too long. Stop waiting for it.
183 * Don't bother to kill it, as we don't care what
187 radlog(L_ERR, "Check-TS: timeout waiting for checkrad");
192 radlog(L_ERR, "Check-TS: unknown error in waitpid()");
196 return WEXITSTATUS(status);
202 * We don't close fd's 0, 1, and 2. If we're in debugging mode,
203 * then they should go to stdout (etc), along with the other
204 * server log messages.
206 * If we're not in debugging mode, then the code in radiusd.c
207 * takes care of connecting fd's 0, 1, and 2 to /dev/null.
210 ip_ntoa(address, nasaddr);
211 snprintf(port, 11, "%u", portnum);
214 /* OS/2 can't directly execute scripts then we call the command
215 processor to execute checkrad
217 execl(getenv("COMSPEC"), "", "/C","checkrad", cl->nastype, address, port,
218 user, session_id, NULL);
220 execl(mainconfig.checkrad, "checkrad", cl->nastype, address, port,
221 user, session_id, NULL);
223 radlog(L_ERR, "Check-TS: exec %s: %s", mainconfig.checkrad, strerror(errno));
226 * Exit - 2 means "some error occured".