/* ============================================================================= statement:query(var1, var2, var3...): Injects variables into a prepared statement and returns the number of rows affected. ============================================================================= */ int lua_db_prepared_query(lua_State *L) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ lua_db_prepared_statement *st = 0; apr_status_t rc = 0; const char **vars; int x, have; /*~~~~~~~~~~~~~~~~~~~~~~~*/ /* Fetch the prepared statement and the vars passed */ luaL_checktype(L, 1, LUA_TTABLE); lua_rawgeti(L, 1, 0); luaL_checktype(L, -1, LUA_TUSERDATA); st = (lua_db_prepared_statement*) lua_topointer(L, -1); /* Check if we got enough variables passed on to us. * This, of course, only works for prepped statements made through lua. */ have = lua_gettop(L) - 2; if (st->variables != -1 && have < st->variables ) { lua_pushboolean(L, 0); lua_pushfstring(L, "Error in executing prepared statement: Expected %d arguments, got %d.", st->variables, have); return 2; } vars = apr_pcalloc(st->db->pool, have*sizeof(char *)); for (x = 0; x < have; x++) { vars[x] = lua_tostring(L, x + 2); } /* Fire off the query */ if (st->db && st->db->alive) { /*~~~~~~~~~~~~~~*/ int affected = 0; /*~~~~~~~~~~~~~~*/ rc = apr_dbd_pquery(st->db->driver, st->db->pool, st->db->handle, &affected, st->statement, have, vars); if (rc == APR_SUCCESS) { lua_pushinteger(L, affected); return 1; } else { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ const char *err = apr_dbd_error(st->db->driver, st->db->handle, rc); /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ lua_pushnil(L); if (err) { lua_pushstring(L, err); return 2; } return 1; } } lua_pushboolean(L, 0); lua_pushliteral(L, "Database connection seems to be closed, please reacquire it."); return (2); }
static int authz_dbd_login(request_rec *r, authz_dbd_cfg *cfg, const void *parsed_require_args, const char *action) { int rv; const char *newuri = NULL; int nrows; const char *message; ap_dbd_t *dbd = dbd_handle(r); apr_dbd_prepared_t *query; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; apr_array_header_t *query_parameters; if (cfg->query == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01642) "No query configured for %s!", action); return HTTP_INTERNAL_SERVER_ERROR; } if (dbd == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02902) "No db handle available for %s! " "Check your database access", action); return HTTP_INTERNAL_SERVER_ERROR; } query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING); if (query == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01643) "Error retrieving Query for %s!", action); return HTTP_INTERNAL_SERVER_ERROR; } rv = evaluate_query_parameters(r, parsed_require_args, (void *)&query_parameters); if (rv != OK) { return HTTP_INTERNAL_SERVER_ERROR; } rv = apr_dbd_pquery(dbd->driver, r->pool, dbd->handle, &nrows, query, query_parameters->nelts, (const char **)query_parameters->elts); if (rv == 0) { if (nrows != 1) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01644) "authz_dbd: %s of user %s updated %d rows", action, r->user, nrows); } } else { message = apr_dbd_error(dbd->driver, dbd->handle, rv); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01645) "authz_dbd: query for %s failed; user %s [%s]", action, r->user, message?message:noerror); return HTTP_INTERNAL_SERVER_ERROR; } if (cfg->redirect == 1) { newuri = apr_table_get(r->headers_in, "Referer"); } if (!newuri && cfg->redir_query) { query = apr_hash_get(dbd->prepared, cfg->redir_query, APR_HASH_KEY_STRING); if (query == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01646) "authz_dbd: no redirect query!"); /* OK, this is non-critical; we can just not-redirect */ } else if ((rv = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res, query, 0, r->user, NULL)) == 0) { for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1); rv != -1; rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) { if (rv != 0) { message = apr_dbd_error(dbd->driver, dbd->handle, rv); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01647) "authz_dbd in get_row; action=%s user=%s [%s]", action, r->user, message?message:noerror); } else if (newuri == NULL) { newuri = apr_dbd_get_entry(dbd->driver, row, 0); } /* we can't break out here or row won't get cleaned up */ } } else { message = apr_dbd_error(dbd->driver, dbd->handle, rv); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01648) "authz_dbd/redirect for %s of %s [%s]", action, r->user, message?message:noerror); } } if (newuri != NULL) { r->status = HTTP_MOVED_TEMPORARILY; apr_table_set(r->err_headers_out, "Location", newuri); } authz_dbd_run_client_login(r, OK, action); return OK; }