⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 log_pgsql.c

📁 功能强大的ftp服务器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <config.h>/* PostgreSQL backend, by Cindy Marasco <cindy@getaclue.org> */#ifdef WITH_PGSQL#include "ftpd.h"#include "parser.h"#include "log_pgsql_p.h"#include "log_pgsql.h"#include "messages.h"#include "crypto.h"#ifdef WITH_DMALLOC# include <dmalloc.h>#endifstatic size_t prv_PQescapeString(char * const to, const char * const from,                                 const size_t length){    register const char *source = from;    register char *target = to;    size_t remaining = length;        while (remaining > (size_t) 0U) {        switch (*source) {        case 0:            remaining = (size_t) 1U;            break;        case '\r':            *target++ = '\\';            *target++ = 'r';                        break;        case '\n':            *target++ = '\\';            *target++ = 'n';            break;        case '\b':            *target++ = '\\';            *target++ = 'b';            break;                    case '\\':        case '\'':        case '"':            *target++ = '\\';        default:            *target++ = *source;        }        source++;        remaining--;            }        *target = 0;        return (size_t) (target - to);}static int pw_pgsql_validate_name(const char *name){    if (name == NULL || *name == 0) {        return -1;    }    do {        if ((*name >= 'a' && *name <= 'z') ||            (*name >= 'A' && *name <= 'Z') ||            (*name >= '0' && *name <= '9') ||            *name == ' ' || *name == '-' ||            *name == '_' || *name == '\'' || *name == '.' ||            *name == ':' || *name == '@') {            /* God bless the Perl 'unless' keyword */        } else {            return -1;        }                    name++;    } while (*name != 0);        return 0;}static char *pw_pgsql_escape_string(const char *from){    size_t from_len;    size_t to_len;    char *to;    size_t tolen;                    if (from == NULL) {        return NULL;    }    from_len = strlen(from);    to_len = from_len * 2U + (size_t) 1U;    if ((to = malloc(to_len)) == NULL) {        return NULL;    }    tolen = prv_PQescapeString(to, from, from_len);    if (tolen >= to_len) {        for (;;) {            *to++ = 0;        }    }    to[tolen] = 0;                    return to;}/* * Substitute digraphs for SQL requests. * orig_str is the original string, from the configuration file * full of \L, \I, \P, \R and \D. * query is a buffer to handle the result. * query_len is the size of the buffer. * returns the buffer @ if successful, NULL otherwise.   -frank. */static char *sqlsubst(const char *orig_str, char * const query,                      size_t query_len, const char * const user,                      const char * const ip, const char * const port,                      const char * const peer_ip,                      const char * const decimal_ip){    char *query_pnt = query;    const char *orig_str_scan = orig_str;    const size_t user_len = (user == NULL ? (size_t) 0U : strlen(user));    const size_t ip_len = (ip == NULL ? (size_t) 0U : strlen(ip));    const size_t port_len = (port == NULL ? (size_t) 0U : strlen(port));    const size_t peer_ip_len = (peer_ip == NULL ? (size_t) 0U : strlen(peer_ip));    const size_t decimal_ip_len = (decimal_ip == NULL ? (size_t) 0U : strlen(decimal_ip));    while (*orig_str_scan != 0) {        if (*orig_str_scan == '\\' && orig_str_scan[1] != 0) {            orig_str_scan++;            switch(tolower((unsigned char) *orig_str_scan)) {            case 'l' :                if (user_len >= query_len) {                    return NULL;                }                if (user_len <= (size_t) 0U) {                    goto nextone;                }                memcpy(query_pnt, user, user_len);                query_pnt += user_len;                query_len -= user_len;                goto nextone;            case 'i' :                if (ip_len >= query_len) {                    return NULL;                }                if (ip_len <= (size_t) 0U) {                    goto nextone;                }                                memcpy(query_pnt, ip, ip_len);                query_pnt += ip_len;                query_len -= ip_len;                goto nextone;            case 'p' :                             if (port_len >= query_len) {                    return NULL;                }                 if (port_len <= (size_t) 0U) {                    goto nextone;                }                               memcpy(query_pnt, port, port_len);                query_pnt += port_len;                query_len -= port_len;                goto nextone;            case 'r' :                             if (peer_ip_len >= query_len) {                    return NULL;                }                 if (peer_ip_len <= (size_t) 0U) {                    goto nextone;                }                               memcpy(query_pnt, peer_ip, peer_ip_len);                query_pnt += peer_ip_len;                query_len -= peer_ip_len;                goto nextone;            case 'd' :                             if (decimal_ip_len >= query_len) {                    return NULL;                }                 if (decimal_ip_len <= (size_t) 0U) {                    goto nextone;                }                               memcpy(query_pnt, decimal_ip, decimal_ip_len);                query_pnt += decimal_ip_len;                query_len -= decimal_ip_len;                goto nextone;            default :                if (--query_len <= (size_t) 0U) {                    return NULL;                }                *query_pnt++ = '\\';            }        }        if (ISCTRLCODE(*orig_str_scan)) {            goto nextone;        }        if (--query_len <= (size_t) 0U) {            return NULL;        }        *query_pnt++ = *orig_str_scan;        nextone:        orig_str_scan++;    }    *query_pnt = 0;    return query;}static int pw_pgsql_connect(PGconn ** const id_sql_server){    char *conninfo = NULL;    size_t sizeof_conninfo;    char *escaped_server = NULL;    char *escaped_db = NULL;    char *escaped_user = NULL;    char *escaped_pw = NULL;    int ret = -1;    *id_sql_server = NULL;        if ((escaped_server = pw_pgsql_escape_string(server)) == NULL ||        (escaped_db = pw_pgsql_escape_string(db)) == NULL ||                (escaped_user = pw_pgsql_escape_string(user)) == NULL ||        (escaped_pw = pw_pgsql_escape_string(pw)) == NULL) {        goto bye;    }    #define PGSQL_CONNECT_FMTSTRING \"host='%s' port='%d' dbname='%s' user='%s' password='%s'"            sizeof_conninfo = sizeof PGSQL_CONNECT_FMTSTRING +        strlen(escaped_server) + (size_t) 5U + strlen(escaped_db) +         strlen(escaped_user) + strlen(escaped_pw);    if ((conninfo = malloc(sizeof_conninfo)) == NULL) {        goto bye;    }    if (SNCHECK(snprintf(conninfo, sizeof_conninfo,                         PGSQL_CONNECT_FMTSTRING,                          server, port, db, user, pw), sizeof_conninfo)) {        goto bye;    }        if ((*id_sql_server = PQconnectdb(conninfo)) == NULL ||        PQstatus(*id_sql_server) == CONNECTION_BAD) {        free(conninfo);	if (server_down == 0) {	    server_down++;	    logfile(LOG_ERR, MSG_SQL_DOWN);	}        goto bye;    }    server_down = 0;    ret = 0;        bye:    free(conninfo);    free(escaped_server);    free(escaped_db);    free(escaped_user);    free(escaped_pw);    return ret;}static int pw_pgsql_simplequery(PGconn * const id_sql_server,                                const char * const query){    PGresult *result;    if ((result = PQexec(id_sql_server, query)) == NULL) {        return -1;    }    if (PQresultStatus(result) != PGRES_COMMAND_OK) {        PQclear(result);        	return -1;    }    PQclear(result);        return 0;}static char *pw_pgsql_getquery(PGconn * const id_sql_server,                               const char * const orig_query,                               const char * const account,                               const char * const ip,                               const char * const port,                               const char * const peer_ip,                               const char * const decimal_ip){    PGresult *qresult = NULL;    size_t length;    char *answer = NULL;    char query[PGSQL_MAX_REQUEST_LENGTH];    if (orig_query == NULL || *orig_query == 0) {        goto bye;    }    if (sqlsubst(orig_query, query, sizeof query,                 account, ip, port, peer_ip, decimal_ip) == NULL) {        goto bye;    }    if ((qresult = PQexec(id_sql_server, query)) == NULL) {        logfile(LOG_WARNING, MSG_SQL_WRONG_PARMS " : [%s]", query);                goto bye;    }    if (PQresultStatus(qresult) != PGRES_TUPLES_OK ||        PQnfields(qresult) != 1 ||        PQntuples(qresult) != 1 ||        PQgetisnull(qresult, 0, 0)) {        goto bye;    }    if ((length = (size_t) PQgetlength(qresult, 0, 0) + (size_t) 1U)        <= (size_t) 1U || (answer = malloc(length)) == NULL) {        goto bye;    }    strncpy(answer, PQgetvalue(qresult, 0, 0), length - (size_t) 1U);    answer[length - (size_t) 1U] = 0;        bye:    if (qresult != NULL) {        PQclear(qresult);    }        return answer;    }void pw_pgsql_check(AuthResult * const result,                    const char *account, const char *password,                    const struct sockaddr_storage * const sa,                    const struct sockaddr_storage * const peer){    PGconn *id_sql_server = NULL;    const char *spwd = NULL;           /* stored password */    const char *uid = sql_default_uid; /* stored system login/uid */    const char *gid = sql_default_gid; /* stored system group/gid */    const char *dir = NULL;            /* stored home directory */#ifdef QUOTAS    const char *sqta_fs = NULL;        /* stored quota files */        const char *sqta_sz = NULL;        /* stored quota size */#endif    #ifdef RATIOS    const char *ratio_ul = NULL;       /* stored ratio UL */    const char *ratio_dl = NULL;       /* stored ratio DL */#endif    #ifdef THROTTLING    const char *bandwidth_ul = NULL;   /* stored bandwidth UL */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -