void tac_script_set_exec_context(tac_session * session, char *username, char *portname, char *ctxname) { rb_node_t *rb = NULL; struct shellctx *sc; if (!session->ctx->single_connection_flag) { if (!session->ctx->single_connection_did_warn) { session->ctx->single_connection_did_warn = BISTATE_YES; report(session, LOG_INFO, ~0, "%s: Possibly no single-connection support. " "Context feature may or may not work.", session->ctx->nas_address_ascii); } } if (!session->ctx->shellctxcache && (!ctxname || !*ctxname)) return; if (session->ctx->shellctxcache) rb = tac_script_lookup_exec_context(session, username, portname); else session->ctx->shellctxcache = RB_tree_new(shellctx_cmp, shellctx_free); if (rb) { if (!ctxname || !*ctxname) { RB_delete(session->ctx->shellctxcache, rb); return; } sc = RB_payload(rb, struct shellctx *); free(sc->ctxname); } else {
static void mavis_io(struct context *ctx) { av_ctx *avc = NULL; struct query *q; rb_node_t *r; char *serial; Debug((DEBUG_PROC, "mavis_io %p\n", ctx)); switch (mavis_recv(mcx, &avc, ctx)) { case MAVIS_FINAL: break; case MAVIS_TIMEOUT: counter_expired++, counter_p_expired++; default: return; } if (!(serial = av_get(avc, AV_A_SERIAL))) return; q = alloca(sizeof(struct query)); q->serial = serial; q->serial_crc = crc32_update(INITCRC32, (u_char *) serial, strlen(serial)); if (!(r = RB_search(deferred_by_serial, q))) return; q = RB_payload(r, struct query *); /* XXX -- move the unset functionality to a separate module? */ if (!transmit_password) { av_unset(avc, AV_A_PASSWORD); av_unset(avc, AV_A_DBPASSWORD); } ctx = io_get_ctx(io, q->fd); /* Send answer to client */ av_send(avc, q->fd, &q->sa, ctx->blowfish); /* Remove query from deferred queue */ RB_delete(deferred_by_serial, r); backlog--; setproctitle("%s: backlog: %d", common_data.progname, backlog); counter_answered++, counter_p_answered++; return; } /* if */
static void read_from_child(struct context *ctx, int cur) { ssize_t len; DebugIn(DEBUG_MAVIS); len = Read(ctx->fd_in, ctx->b_in + ctx->b_in_len, sizeof(ctx->b_in) - ctx->b_in_len - 1); if (len > 0) { char *t; int matchlevel = 0; Debug((DEBUG_PROC, "%s:%d %s\n", __FILE__, __LINE__, ctx->mcx->path)); ctx->b_in_len += len; ctx->b_in[ctx->b_in_len] = 0; for (t = ctx->b_in + ctx->b_in_len - 1; t > ctx->b_in; t--) switch (matchlevel) { case 0: if (*t != '\n') { DebugOut(DEBUG_MAVIS); return; } matchlevel++; break; case 1: if (!isdigit((int) *t)) { DebugOut(DEBUG_MAVIS); return; } matchlevel++; break; case 2: if (!isdigit((int) *t) && *t != '-' && *t != '=') { DebugOut(DEBUG_MAVIS); return; } if (*t == '=') matchlevel++; break; case 3: if (*t == '\n') { rb_node_t *r; struct query *q; char *serial = av_get(ctx->ac, AV_A_SERIAL); char *serial_old = alloca(strlen(serial) + 1); int result; strcpy(serial_old, serial); io_clr_i(ctx->mcx->io, ctx->fd_in); av_clear(ctx->ac); *++t = 0; av_char_to_array(ctx->ac, ctx->b_in, NULL); result = atoi(++t); ctx->in_use = 0; ctx->mcx->usage--; serial = av_get(ctx->ac, AV_A_SERIAL); if (!serial || strcmp(serial, serial_old)) { if (serial) logmsg("%s: %lu: out of sync: " "got %s, expected %s. Terminating.", ctx->mcx->argv[0], (u_long) ctx->pid, serial, serial_old); else logmsg("%s: %lu: missing serial. Terminating.", ctx->mcx->argv[0], (u_long) ctx->pid); av_free(ctx->ac); ctx->ac = NULL; kill(ctx->pid, SIGTERM); child_died(ctx, ctx->fd_in); DebugOut(DEBUG_MAVIS); return; } q = Xcalloc(1, sizeof(struct context)); q->ac = ctx->ac; ctx->ac = NULL; q->result = result; q->canceled = ctx->canceled; ctx->canceled = 0; RB_insert(ctx->mcx->outgoing, q); #ifdef DEBUG_RB fprintf(stderr, "EXT insert outgoing %p\n", q); #endif if (ctx->mcx->io_context_parent) { if (!RB_empty(ctx->mcx->backlog_fifo)) { rb_node_t *rbn = RB_first(ctx->mcx->backlog_fifo); struct query *qp = RB_payload(rbn, struct query *); Debug((DEBUG_PROC, "%s:%d\n", __FILE__, __LINE__)); RB_search_and_delete(ctx->mcx->backlog_app_ctx, qp); RB_search_and_delete(ctx->mcx->backlog_serial, qp); ctx->ac = qp->ac; qp->ac = NULL; RB_delete(ctx->mcx->backlog_fifo, rbn); #ifdef DEBUG_RB fprintf(stderr, "EXT remove backlog_fifo %p\n", RB_payload(rbn, void *)); #endif ctx->mcx->backlog_cur--; ctx->mcx->usage++; ctx->mcx->cx_stat[ctx->index].counter++; ctx->mcx->cx_stat[ctx->index].counter_p++; start_query(ctx); } while ((r = RB_first(ctx->mcx->outgoing))) { struct query *qp = RB_payload(r, struct query *); if (ctx->mcx->ac_bak) av_free(ctx->mcx->ac_bak); ctx->mcx->ac_bak = qp->ac_bak; qp->ac_bak = NULL; if (q->canceled) { av_free(ctx->mcx->ac_bak); ctx->mcx->ac_bak = NULL; RB_delete(ctx->mcx->outgoing, r); } else ((void (*)(void *)) qp->ac->app_cb) (qp->ac->app_ctx); } } DebugOut(DEBUG_MAVIS); return; }