📄 authreg_pgsql.c
字号:
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002-2003 Jeremie Miller, Thomas Muldowney, * Ryan Eatmon, Robert Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA *//* this module talks to a PostgreSQL server via libpq */#include "c2s.h"#ifdef STORAGE_PGSQL#include <libpq-fe.h>#define PGSQL_LU 1024 /* maximum length of username - should correspond to field length */#define PGSQL_LR 256 /* maximum length of realm - should correspond to field length */#define PGSQL_LP 256 /* maximum length of password - should correspond to field length */typedef struct pgsqlcontext_st { PGconn * conn; char * sql_create; char * sql_select; char * sql_setpassword; char * sql_setzerok; char * sql_delete; char * field_password; char * field_hash; char * field_token; char * field_sequence; } *pgsqlcontext_t;static PGresult *_ar_pgsql_get_user_tuple(authreg_t ar, char *username, char *realm) { pgsqlcontext_t ctx = (pgsqlcontext_t) ar->private; PGconn *conn = ctx->conn; char iuser[PGSQL_LU+1], irealm[PGSQL_LR+1]; char euser[PGSQL_LU*2+1], erealm[PGSQL_LR*2+1], sql[1024+PGSQL_LU*2+PGSQL_LR*2+1]; /* query(1024) + euser + erealm + \0(1) */ PGresult *res; snprintf(iuser, PGSQL_LU+1, "%s", username); snprintf(irealm, PGSQL_LR+1, "%s", realm); PQescapeString(euser, iuser, strlen(iuser)); PQescapeString(erealm, irealm, strlen(irealm)); sprintf(sql, ctx->sql_select, euser, erealm); log_debug(ZONE, "prepared sql: %s", sql); res = PQexec(conn, sql); if(PQresultStatus(res) != PGRES_TUPLES_OK && PQstatus(conn) != CONNECTION_OK) { log_write(ar->c2s->log, LOG_ERR, "pgsql: lost connection to database, attempting reconnect"); PQclear(res); PQreset(conn); res = PQexec(conn, sql); } if(PQresultStatus(res) != PGRES_TUPLES_OK) { log_write(ar->c2s->log, LOG_ERR, "pgsql: sql select failed: %s", PQresultErrorMessage(res)); PQclear(res); return NULL; } if(PQntuples(res) != 1) { PQclear(res); return NULL; } return res;}static int _ar_pgsql_user_exists(authreg_t ar, char *username, char *realm) { PGresult *res = _ar_pgsql_get_user_tuple(ar, username, realm); if(res != NULL) { PQclear(res); return 1; } return 0;}static int _ar_pgsql_get_password(authreg_t ar, char *username, char *realm, char password[257]) { pgsqlcontext_t ctx = (pgsqlcontext_t) ar->private; PGresult *res = _ar_pgsql_get_user_tuple(ar, username, realm); int fpass; if(res == NULL) return 1; fpass = PQfnumber(res, ctx->field_password); if(fpass == -1) { log_debug(ZONE, "weird, password field wasn't returned"); PQclear(res); return 1; } if(PQgetisnull(res, 0, fpass)) { PQclear(res); return 1; } strcpy(password, PQgetvalue(res, 0, fpass)); PQclear(res); return 0;}static int _ar_pgsql_set_password(authreg_t ar, char *username, char *realm, char password[257]) { pgsqlcontext_t ctx = (pgsqlcontext_t) ar->private; PGconn *conn = ctx->conn; char iuser[PGSQL_LU+1], irealm[PGSQL_LR+1]; char euser[PGSQL_LU*2+1], erealm[PGSQL_LR*2+1], epass[513], sql[1024+PGSQL_LU*2+PGSQL_LR*2+512+1]; /* query(1024) + euser + erealm + epass(512) + \0(1) */ PGresult *res; snprintf(iuser, PGSQL_LU+1, "%s", username); snprintf(irealm, PGSQL_LR+1, "%s", realm); PQescapeString(euser, iuser, strlen(iuser)); PQescapeString(erealm, irealm, strlen(irealm)); PQescapeString(epass, password, strlen(password)); sprintf(sql, ctx->sql_setpassword, epass, euser, erealm); log_debug(ZONE, "prepared sql: %s", sql); res = PQexec(conn, sql); if(PQresultStatus(res) != PGRES_COMMAND_OK && PQstatus(conn) != CONNECTION_OK) { log_write(ar->c2s->log, LOG_ERR, "pgsql: lost connection to database, attempting reconnect"); PQclear(res); PQreset(conn); res = PQexec(conn, sql); } if(PQresultStatus(res) != PGRES_COMMAND_OK) { log_write(ar->c2s->log, LOG_ERR, "pgsql: sql update failed: %s", PQresultErrorMessage(res)); PQclear(res); return 1; } PQclear(res); return 0;}static int _ar_pgsql_get_zerok(authreg_t ar, char *username, char *realm, char hash[41], char token[11], int *sequence) { pgsqlcontext_t ctx = (pgsqlcontext_t) ar->private; PGresult *res = _ar_pgsql_get_user_tuple(ar, username, realm); int fhash, ftok, fseq; if(res == NULL) return 1; fhash = PQfnumber(res, ctx->field_hash); ftok = PQfnumber(res, ctx->field_token); fseq = PQfnumber(res, ctx->field_sequence); if(fhash == -1 || ftok == -1 || fseq == -1) { log_debug(ZONE, "weird, required field wasn't returned"); PQclear(res); return 1; } if(PQgetisnull(res, 0, fhash) || PQgetisnull(res, 0, ftok) || PQgetisnull(res, 0, fseq)) { PQclear(res); return 1; } strcpy(hash, PQgetvalue(res, 0, fhash)); strcpy(token, PQgetvalue(res, 0, ftok)); *sequence = atoi(PQgetvalue(res, 0, fseq)); PQclear(res); return 0;}static int _ar_pgsql_set_zerok(authreg_t ar, char *username, char *realm, char hash[41], char token[11], int sequence) { pgsqlcontext_t ctx = (pgsqlcontext_t) ar->private; PGconn *conn = ctx->conn; char iuser[PGSQL_LU+1], irealm[PGSQL_LR+1]; char euser[PGSQL_LU*2+1], erealm[PGSQL_LR*2+1], ehash[81], etoken[21], sql[1024 + PGSQL_LU*2 + PGSQL_LR*2 + 80 + 20 + 12 + 1]; /* query(1024) + euser + erealm + ehash(80) + etoken(20) + sequence(12) + \0(1) */ PGresult *res; snprintf(iuser, PGSQL_LU+1, "%s", username); snprintf(irealm, PGSQL_LR+1, "%s", realm); PQescapeString(euser, iuser, strlen(iuser)); PQescapeString(erealm, irealm, strlen(irealm)); PQescapeString(ehash, hash, strlen(hash)); PQescapeString(etoken, token, strlen(token)); sprintf(sql, ctx->sql_setzerok, ehash, etoken, sequence, euser, erealm); log_debug(ZONE, "prepared sql: %s", sql); res = PQexec(conn, sql); if(PQresultStatus(res) != PGRES_COMMAND_OK && PQstatus(conn) != CONNECTION_OK) { log_write(ar->c2s->log, LOG_ERR, "pgsql: lost connection to database, attempting reconnect"); PQclear(res); PQreset(conn); res = PQexec(conn, sql); } if(PQresultStatus(res) != PGRES_COMMAND_OK) { log_write(ar->c2s->log, LOG_ERR, "pgsql: sql update failed: %s", PQresultErrorMessage(res)); PQclear(res); return 1; } PQclear(res); return 0;}static int _ar_pgsql_create_user(authreg_t ar, char *username, char *realm) { pgsqlcontext_t ctx = (pgsqlcontext_t) ar->private; PGconn *conn = ctx->conn; char iuser[PGSQL_LU+1], irealm[PGSQL_LR+1]; char euser[PGSQL_LU*2+1], erealm[PGSQL_LR*2+1], sql[1024+PGSQL_LU*2+PGSQL_LR*2+1]; /* query(1024) + euser + erealm + \0(1) */ PGresult *res; res = _ar_pgsql_get_user_tuple(ar, username, realm); if(res != NULL) { PQclear(res); return 1; } PQclear(res); snprintf(iuser, PGSQL_LU+1, "%s", username); snprintf(irealm, PGSQL_LR+1, "%s", realm); PQescapeString(euser, iuser, strlen(iuser)); PQescapeString(erealm, irealm, strlen(irealm)); sprintf(sql, ctx->sql_create, euser, erealm); log_debug(ZONE, "prepared sql: %s", sql); res = PQexec(conn, sql); if(PQresultStatus(res) != PGRES_COMMAND_OK && PQstatus(conn) != CONNECTION_OK) { log_write(ar->c2s->log, LOG_ERR, "pgsql: lost connection to database, attempting reconnect"); PQclear(res); PQreset(conn); res = PQexec(conn, sql); } if(PQresultStatus(res) != PGRES_COMMAND_OK) { log_write(ar->c2s->log, LOG_ERR, "pgsql: sql insert failed: %s", PQresultErrorMessage(res)); PQclear(res); return 1; } PQclear(res);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -