got_alrm = 1;
}
-/*************************************************************************
- *
- * Function: sql_check_ts
- *
- * Purpose: Checks the terminal server for a spacific login entry
- *
- *************************************************************************/
-static int sql_check_ts(SQL_ROW row) {
-
- int pid, st, e;
- int n;
- NAS *nas;
- char session_id[12];
- char *s;
- void (*handler) (int);
-
- /*
- * Find NAS type.
- */
- if ((nas = nas_find(ip_addr(row[4]))) == NULL) {
- radlog(L_ERR, "rlm_sql: unknown NAS [%s]", row[4]);
- return -1;
- }
-
- /*
- * Fork.
- */
- handler = signal(SIGCHLD, SIG_DFL);
- if ((pid = fork()) < 0) {
- radlog(L_ERR, "rlm_sql: fork: %s", strerror(errno));
- signal(SIGCHLD, handler);
- return -1;
- }
-
- if (pid > 0) {
- /*
- * Parent - Wait for checkrad to terminate.
- * We timeout in 10 seconds.
- */
- got_alrm = 0;
- signal(SIGALRM, alrm_handler);
- alarm(10);
- while ((e = waitpid(pid, &st, 0)) != pid)
- if (e < 0 && (errno != EINTR || got_alrm))
- break;
- alarm(0);
- signal(SIGCHLD, handler);
- if (got_alrm) {
- kill(pid, SIGTERM);
- sleep(1);
- kill(pid, SIGKILL);
- radlog(L_ERR, "rlm_sql: Check-TS: timeout waiting for checkrad");
- return 2;
- }
- if (e < 0) {
- radlog(L_ERR, "rlm_sql: Check-TS: unknown error in waitpid()");
- return 2;
- }
- return WEXITSTATUS(st);
- }
-
- /*
- * Child - exec checklogin with the right parameters.
- */
- for (n = 32; n >= 3; n--)
- close(n);
-
- sprintf(session_id, "%.8s", row[1]);
-
- s = CHECKRAD2;
- execl(CHECKRAD2, "checkrad", nas->nastype, row[4], row[5],
- row[2], session_id, NULL);
- if (errno == ENOENT) {
- s = CHECKRAD1;
- execl(CHECKRAD1, "checklogin", nas->nastype, row[4], row[5],
- row[2], session_id, NULL);
- }
- radlog(L_ERR, "rlm_sql: Check-TS: exec %s: %s", s, strerror(errno));
-
- /*
- * Exit - 2 means "some error occured".
- */
- exit(2);
- return -1;
-}
-
-
-/*************************************************************************
- *
- * Function: sql_check_multi
- *
- * Purpose: Check radius accounting for duplicate logins
- *
- *************************************************************************/
-int sql_check_multi(SQL_INST * inst, SQLSOCK * sqlsocket, char *name, VALUE_PAIR * request, int maxsimul) {
-
- char querystr[MAX_QUERY_LEN];
- char authstr[256];
- VALUE_PAIR *fra;
- SQL_ROW row;
- int count = 0;
- uint32_t ipno = 0;
- int mpp = 1;
-
- sprintf(authstr, "UserName = '%s'", name);
- sprintf(querystr, "SELECT COUNT(*) FROM %s WHERE %s AND AcctStopTime = 0", inst->config->sql_acct_table, authstr);
-
-
- if (rlm_sql_select_query(sqlsocket, inst, querystr)) {
- radlog(L_ERR, "sql_check_multi: database query error");
- return -1;
- }
-
- if (rlm_sql_fetch_row(sqlsocket, inst->config)) {
- (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
- return -1;
- }
-
- row = sqlsocket->row;
- if (row != NULL) {
- count = atoi(row[0]);
- } else {
- count = 0;
- }
- (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-
- if (count < maxsimul)
- return 0;
-
- /*
- * * Setup some stuff, like for MPP detection.
- */
- if ((fra = pairfind(request, PW_FRAMED_IP_ADDRESS)) != NULL)
- ipno = htonl(fra->lvalue);
-
- count = 0;
- sprintf(querystr, "SELECT * FROM %s WHERE %s AND AcctStopTime = 0", inst->config->sql_acct_table, authstr);
-
- if (rlm_sql_select_query(sqlsocket, inst, querystr)) {
- radlog(L_ERR, "sql_check_multi: database query error");
- return -1;
- }
- while (rlm_sql_fetch_row(sqlsocket, inst) == 0) {
- int check;
- row = sqlsocket->row;
- if (row == NULL) {
- break;
- }
- check = sql_check_ts(row);
-
- if (check == 1) {
- count++;
-
- if (ipno && atoi(row[19]) == ipno)
- mpp = 2;
-
- } else if (check == 2)
- radlog(L_ERR, "rlm_sql: Problem with checkrad [%s] (from nas %s)", name, row[4]);
- else {
- /*
- * False record - zap it
- */
-
- if (inst->config->deletestalesessions) {
- SQLSOCK *sqlsocket1;
-
- radlog(L_ERR, "rlm_sql: Deleteing stale session [%s] (from nas %s/%s)", row[2], row[4], row[5]);
- sqlsocket1 = sql_get_socket(inst);
- sprintf(querystr, "DELETE FROM %s WHERE RadAcctId = '%s'", inst->config->sql_acct_table, row[0]);
- if(rlm_sql_query(sqlsocket1, inst, querystr)) {
- radlog(L_ERR, "rlm_sql: database query error");
- } else {
- (inst->module->sql_finish_query)(sqlsocket1, inst->config);
- sql_release_socket(inst, sqlsocket1);
- }
- }
- }
- }
- (inst->module->sql_finish_select_query)(sqlsocket, inst->config);
-
- return (count < maxsimul) ? 0 : mpp;
-}
-
void query_log(SQL_INST * inst, char *querystr) {
FILE *sqlfile = NULL;