Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| #include <config.h> | |
| #ifdef WITH_MYSQL | |
| # include "ftpd.h" | |
| # include "parser.h" | |
| # include "log_mysql_p.h" | |
| # include "log_mysql.h" | |
| # include "messages.h" | |
| # include "crypto.h" | |
| # include "crypto-sha1.h" | |
| # include "alt_arc4random.h" | |
| # include "utils.h" | |
| #ifdef HAVE_LIBSODIUM | |
| # include <sodium.h> | |
| #endif | |
| #ifdef WITH_DMALLOC | |
| # include <dmalloc.h> | |
| # endif | |
| static int pw_mysql_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 == '@' || *name == '+') { | |
| /* God bless the Ruby 'unless' keyword */ | |
| } else { | |
| return -1; | |
| } | |
| name++; | |
| } while (*name != 0); | |
| return 0; | |
| } | |
| static char *pw_mysql_escape_string(MYSQL * const id_sql_server, | |
| const char *from) | |
| { | |
| size_t from_len; | |
| size_t to_len; | |
| char *to; | |
| unsigned long escaped_len; | |
| unsigned int t; | |
| unsigned char t1, t2, t3, t4; | |
| if (from == NULL) { | |
| return NULL; | |
| } | |
| from_len = strlen(from); | |
| to_len = from_len * 2U + (size_t) 1U; | |
| if ((to = malloc(to_len + (size_t) 4U)) == NULL) { | |
| return NULL; | |
| } | |
| t = zrand(); | |
| t1 = t & 0xff; | |
| t2 = (t >> 8) & 0xff; | |
| t = zrand(); | |
| t3 = t & 0xff; | |
| t4 = (t >> 8) & 0xff; | |
| to[to_len] = (char) t1; | |
| to[to_len + 1] = (char) t2; | |
| to[to_len + 2] = (char) t3; | |
| to[to_len + 3] = (char) t4; | |
| /* | |
| * I really hate giving a buffer without any size to a 3rd party function. | |
| * The "to" buffer is allocated on the heap, not on the stack, if | |
| * mysql_real_escape_string() is buggy, the stack shouldn't be already | |
| * smashed at this point, but data from other malloc can be corrupted and | |
| * bad things can happen. It make sense to wipe this area as soon as | |
| * possible instead of doing anything with the heap. We'll end up with | |
| * a segmentation violation, but without any possible exploit. | |
| */ | |
| escaped_len = mysql_real_escape_string(id_sql_server, to, from, from_len); | |
| if (escaped_len >= to_len || | |
| (unsigned char) to[to_len] != t1 || | |
| (unsigned char) to[to_len + 1] != t2 || | |
| (unsigned char) to[to_len + 2] != t3 || | |
| (unsigned char) to[to_len + 3] != t4) { | |
| for (;;) { | |
| *to++ = 0; | |
| } | |
| } | |
| to[escaped_len] = 0; | |
| return to; | |
| } | |
| /* | |
| * Substitute digraphs for SQL requests. | |
| * orig_str is the original string, 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_mysql_connect(MYSQL ** const id_sql_server) | |
| { | |
| *id_sql_server = NULL; | |
| if ((*id_sql_server = mysql_init(NULL)) == NULL) { | |
| down: | |
| if (server_down == 0) { | |
| const char *mysql_err = "mysql_init()"; | |
| if (*id_sql_server != NULL) { | |
| mysql_err = mysql_error(*id_sql_server); | |
| } | |
| server_down++; | |
| logfile(LOG_ERR, MSG_SQL_DOWN " [%s]", mysql_err); | |
| } | |
| return -1; | |
| } | |
| if (mysql_real_connect(*id_sql_server, server, user, pw, | |
| db, port, socket_path, | |
| #ifdef CLIENT_MULTI_STATEMENTS | |
| CLIENT_MULTI_STATEMENTS | |
| #else | |
| 0 | |
| #endif | |
| ) == NULL) { | |
| goto down; | |
| } | |
| if (mysql_ping(*id_sql_server) != 0) { | |
| goto down; | |
| } | |
| server_down = 0; | |
| return 0; | |
| } | |
| static int pw_mysql_simplequery(MYSQL * const id_sql_server, | |
| const char * const query) | |
| { | |
| if (mysql_real_query(id_sql_server, query, strlen(query)) != 0) { | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| static char *pw_mysql_getquery(MYSQL * 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) | |
| { | |
| char query[MYSQL_MAX_REQUEST_LENGTH]; | |
| MYSQL_RES *qresult = NULL; | |
| unsigned long *lengths; | |
| char *answer = NULL; | |
| MYSQL_ROW row; | |
| size_t 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 (mysql_real_query(id_sql_server, query, strlen(query)) != 0) { | |
| logfile(LOG_WARNING, MSG_SQL_WRONG_PARMS " : [%s]", query); | |
| goto bye; | |
| } | |
| if (mysql_field_count(id_sql_server) != 1) { | |
| goto bye; | |
| } | |
| if ((qresult = mysql_store_result(id_sql_server)) == NULL) { | |
| goto bye; | |
| } | |
| if (mysql_num_rows(qresult) != 1) { | |
| goto bye; | |
| } | |
| if ((row = mysql_fetch_row(qresult)) == NULL || row[0] == NULL) { | |
| goto bye; | |
| } | |
| lengths = mysql_fetch_lengths(qresult); | |
| if (lengths == NULL || | |
| (length = (size_t) lengths[0] + (size_t) 1U) <= (size_t) 1U) { | |
| goto bye; | |
| } | |
| if ((answer = malloc(length)) == NULL) { | |
| goto bye; | |
| } | |
| strncpy(answer, row[0], length - (size_t) 1U); | |
| answer[length - (size_t) 1U] = 0; | |
| bye: | |
| if (qresult != NULL) { | |
| mysql_free_result(qresult); | |
| #ifdef CLIENT_MULTI_STATEMENTS | |
| while (mysql_next_result(id_sql_server) == 0) { | |
| qresult = mysql_store_result(id_sql_server); | |
| mysql_free_result(qresult); | |
| } | |
| #endif | |
| } | |
| return answer; | |
| } | |
| void pw_mysql_check(AuthResult * const result, | |
| const char *account, const char *password, | |
| const struct sockaddr_storage * const sa, | |
| const struct sockaddr_storage * const peer) | |
| { | |
| MYSQL *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 */ | |
| const char *bandwidth_dl = NULL; /* stored bandwidth DL */ | |
| #endif | |
| char *escaped_account = NULL; | |
| char *escaped_ip = NULL; | |
| char *escaped_port = NULL; | |
| char *escaped_peer_ip = NULL; | |
| char *escaped_decimal_ip = NULL; | |
| int committed = 1; | |
| int crypto_argon2i = 0, crypto_scrypt = 0, crypto_crypt = 0, | |
| crypto_mysql = 0, crypto_md5 = 0, crypto_sha1 = 0, crypto_plain = 0; | |
| unsigned long decimal_ip_num = 0UL; | |
| char decimal_ip[42]; | |
| char hbuf[NI_MAXHOST]; | |
| char pbuf[NI_MAXSERV]; | |
| char phbuf[NI_MAXHOST]; | |
| result->auth_ok = 0; | |
| if (pw_mysql_validate_name(account) != 0) { | |
| goto bye; | |
| } | |
| if (getnameinfo((const struct sockaddr *) sa, STORAGE_LEN(*sa), | |
| hbuf, sizeof hbuf, pbuf, sizeof pbuf, | |
| NI_NUMERICHOST | NI_NUMERICSERV) != 0 || | |
| getnameinfo((const struct sockaddr *) peer, STORAGE_LEN(*peer), | |
| phbuf, sizeof phbuf, NULL, (size_t) 0U, | |
| NI_NUMERICHOST) != 0) { | |
| goto bye; | |
| } | |
| *decimal_ip = 0; | |
| if (STORAGE_FAMILY(*peer) == AF_INET) { | |
| const unsigned char *decimal_ip_raw = | |
| (const unsigned char *) &(STORAGE_SIN_ADDR(*peer)); | |
| decimal_ip_num = ((unsigned long) decimal_ip_raw[0] << 24) | | |
| ((unsigned long) decimal_ip_raw[1] << 16) | | |
| (decimal_ip_raw[2] << 8) | decimal_ip_raw[3]; | |
| if (SNCHECK(snprintf(decimal_ip, sizeof decimal_ip, | |
| "%lu", decimal_ip_num), sizeof decimal_ip)) { | |
| goto bye; | |
| } | |
| } | |
| if (pw_mysql_connect(&id_sql_server) != 0) { | |
| goto bye; | |
| } | |
| if ((escaped_account = | |
| pw_mysql_escape_string(id_sql_server, account)) == NULL) { | |
| goto bye; | |
| } | |
| if ((escaped_ip = | |
| pw_mysql_escape_string(id_sql_server, hbuf)) == NULL) { | |
| goto bye; | |
| } | |
| if ((escaped_port = | |
| pw_mysql_escape_string(id_sql_server, pbuf)) == NULL) { | |
| goto bye; | |
| } | |
| if ((escaped_peer_ip = | |
| pw_mysql_escape_string(id_sql_server, phbuf)) == NULL) { | |
| goto bye; | |
| } | |
| if ((escaped_decimal_ip = | |
| pw_mysql_escape_string(id_sql_server, decimal_ip)) == NULL) { | |
| goto bye; | |
| } | |
| if (transactions != NULL && strcasecmp(transactions, "on") == 0) { | |
| if (pw_mysql_simplequery(id_sql_server, MYSQL_TRANSACTION_START) == 0) { | |
| committed = 0; | |
| } | |
| } | |
| if ((spwd = pw_mysql_getquery(id_sql_server, sqlreq_getpw, | |
| escaped_account, escaped_ip, | |
| escaped_port, escaped_peer_ip, | |
| escaped_decimal_ip)) == NULL) { | |
| goto bye; | |
| } | |
| if (uid == NULL) { | |
| uid = pw_mysql_getquery(id_sql_server, sqlreq_getuid, | |
| escaped_account, escaped_ip, | |
| escaped_port, escaped_peer_ip, | |
| escaped_decimal_ip); | |
| } | |
| if (uid == NULL) { | |
| goto bye; | |
| } | |
| if (gid == NULL) { | |
| gid = pw_mysql_getquery(id_sql_server, sqlreq_getgid, | |
| escaped_account, escaped_ip, | |
| escaped_port, escaped_peer_ip, | |
| escaped_decimal_ip); | |
| } | |
| if (gid == NULL) { | |
| goto bye; | |
| } | |
| if ((dir = pw_mysql_getquery(id_sql_server, sqlreq_getdir, | |
| escaped_account, escaped_ip, | |
| escaped_port, escaped_peer_ip, | |
| escaped_decimal_ip)) == NULL) { | |
| goto bye; | |
| } | |
| result->auth_ok--; /* -1 */ | |
| if (strcasecmp(crypto, PASSWD_SQL_ANY) == 0) { | |
| crypto_argon2i++; | |
| crypto_scrypt++; | |
| crypto_crypt++; | |
| crypto_mysql++; | |
| crypto_md5++; | |
| crypto_sha1++; | |
| } else if (strcasecmp(crypto, PASSWD_SQL_ARGON2I) == 0) { | |
| crypto_argon2i++; | |
| } else if (strcasecmp(crypto, PASSWD_SQL_SCRYPT) == 0) { | |
| crypto_scrypt++; | |
| } else if (strcasecmp(crypto, PASSWD_SQL_CRYPT) == 0) { | |
| crypto_crypt++; | |
| } else if (strcasecmp(crypto, PASSWD_SQL_MYSQL) == 0) { | |
| crypto_mysql++; | |
| } else if (strcasecmp(crypto, PASSWD_SQL_MD5) == 0) { | |
| crypto_md5++; | |
| } else if (strcasecmp(crypto, PASSWD_SQL_SHA1) == 0) { | |
| crypto_sha1++; | |
| } else { /* default to plaintext */ | |
| crypto_plain++; | |
| } | |
| #ifdef HAVE_LIBSODIUM | |
| # ifdef crypto_pwhash_STRPREFIX | |
| if (crypto_argon2i != 0) { | |
| if (crypto_pwhash_str_verify(spwd, password, strlen(password)) == 0) { | |
| goto auth_ok; | |
| } | |
| } | |
| # endif | |
| if (crypto_scrypt != 0) { | |
| if (crypto_pwhash_scryptsalsa208sha256_str_verify | |
| (spwd, password, strlen(password)) == 0) { | |
| goto auth_ok; | |
| } | |
| } | |
| #endif | |
| if (crypto_crypt != 0) { | |
| const char *crypted; | |
| if ((crypted = (const char *) crypt(password, spwd)) != NULL && | |
| pure_strcmp(crypted, spwd) == 0) { | |
| goto auth_ok; | |
| } | |
| } | |
| if (crypto_mysql != 0) { | |
| char scrambled_password[42]; /* 2 * 20 (sha1 hash size) + 2 */ | |
| # ifdef HAVE_MY_MAKE_SCRAMBLED_PASSWORD | |
| my_make_scrambled_password(scrambled_password, password, | |
| strlen(password)); | |
| # elif defined(HAVE_MAKE_SCRAMBLED_PASSWORD) | |
| make_scrambled_password(scrambled_password, password); | |
| # else | |
| { | |
| SHA1_CTX ctx; | |
| unsigned char h0[20], h1[20]; | |
| char *p; | |
| SHA1Init(&ctx); | |
| SHA1Update(&ctx, password, strlen(password)); | |
| SHA1Final(h0, &ctx); | |
| SHA1Init(&ctx); | |
| SHA1Update(&ctx, h0, sizeof h0); | |
| pure_memzero(h0, sizeof h0); | |
| SHA1Final(h1, &ctx); | |
| *scrambled_password = '*'; | |
| hexify(scrambled_password + 1U, h1, | |
| (sizeof scrambled_password) - 1U, sizeof h1); | |
| *(p = scrambled_password) = '*'; | |
| while (*p++ != 0) { | |
| *p = (char) toupper((unsigned char) *p); | |
| } | |
| } | |
| # endif | |
| if (pure_strcmp(scrambled_password, spwd) == 0) { | |
| goto auth_ok; | |
| } | |
| } | |
| if (crypto_md5 != 0) { | |
| const char *crypted; | |
| if ((crypted = (const char *) crypto_hash_md5(password, 1)) != NULL && | |
| pure_strcmp(crypted, spwd) == 0) { | |
| goto auth_ok; | |
| } | |
| } | |
| if (crypto_sha1 != 0) { | |
| const char *crypted; | |
| if ((crypted = (const char *) crypto_hash_sha1(password, 1)) != NULL && | |
| pure_strcmp(crypted, spwd) == 0) { | |
| goto auth_ok; | |
| } | |
| } | |
| if (crypto_plain != 0) { | |
| if (*password != 0 && /* refuse null cleartext passwords */ | |
| pure_strcmp(password, spwd) == 0) { | |
| goto auth_ok; | |
| } | |
| } | |
| goto bye; | |
| auth_ok: | |
| /* | |
| * do *NOT* accept root uid/gid - if the database is compromized, the FTP | |
| * server could also be rooted. | |
| */ | |
| result->uid = (uid_t) strtoul(uid, NULL, 10); | |
| if (result->uid <= (uid_t) 0) { | |
| struct passwd *pw; | |
| if ((pw = getpwnam(uid)) == NULL || pw->pw_uid <= (uid_t) 0) { | |
| goto bye; | |
| } | |
| result->uid = pw->pw_uid; | |
| } | |
| result->gid = (gid_t) strtoul(gid, NULL, 10); | |
| if (result->gid <= (gid_t) 0) { | |
| struct group *gr; | |
| if ((gr = getgrnam(gid)) == NULL || (gid_t) gr->gr_gid <= (gid_t) 0) { | |
| goto bye; | |
| } | |
| result->gid = gr->gr_gid; | |
| } | |
| result->dir = dir; | |
| dir = NULL; | |
| #ifdef QUOTAS | |
| if ((sqta_fs = pw_mysql_getquery(id_sql_server, sqlreq_getqta_fs, | |
| escaped_account, escaped_ip, | |
| escaped_port, escaped_peer_ip, | |
| escaped_decimal_ip)) != NULL) { | |
| const unsigned long long q = strtoull(sqta_fs, NULL, 10); | |
| if (q > 0ULL) { | |
| result->user_quota_files = q; | |
| result->quota_files_changed = 1; | |
| } | |
| } | |
| if ((sqta_sz = pw_mysql_getquery(id_sql_server, sqlreq_getqta_sz, | |
| escaped_account, escaped_ip, | |
| escaped_port, escaped_peer_ip, | |
| escaped_decimal_ip)) != NULL) { | |
| const unsigned long long q = strtoull(sqta_sz, NULL, 10); | |
| if (q > 0ULL) { | |
| result->user_quota_size = q * (1024UL * 1024UL); | |
| result->quota_size_changed = 1; | |
| } | |
| } | |
| #endif | |
| #ifdef RATIOS | |
| if ((ratio_ul = pw_mysql_getquery(id_sql_server, sqlreq_getratio_ul, | |
| escaped_account, escaped_ip, | |
| escaped_port, escaped_peer_ip, | |
| escaped_decimal_ip)) != NULL) { | |
| const unsigned int q = (unsigned int) strtoul(ratio_ul, NULL, 10); | |
| if (q > 0U) { | |
| result->ratio_upload = q; | |
| result->ratio_ul_changed = 1; | |
| } | |
| } | |
| if ((ratio_dl = pw_mysql_getquery(id_sql_server, sqlreq_getratio_dl, | |
| escaped_account, escaped_ip, | |
| escaped_port, escaped_peer_ip, | |
| escaped_decimal_ip)) != NULL) { | |
| const unsigned int q = (unsigned int) strtoul(ratio_dl, NULL, 10); | |
| if (q > 0U) { | |
| result->ratio_download = q; | |
| result->ratio_dl_changed = 1; | |
| } | |
| } | |
| #endif | |
| #ifdef THROTTLING | |
| if ((bandwidth_ul = pw_mysql_getquery(id_sql_server, sqlreq_getbandwidth_ul, | |
| escaped_account, escaped_ip, | |
| escaped_port, escaped_peer_ip, | |
| escaped_decimal_ip)) != NULL) { | |
| const unsigned long q = (unsigned long) strtoul(bandwidth_ul, NULL, 10); | |
| if (q > 0UL) { | |
| result->throttling_bandwidth_ul = q * 1024UL; | |
| result->throttling_ul_changed = 1; | |
| } | |
| } | |
| if ((bandwidth_dl = pw_mysql_getquery(id_sql_server, sqlreq_getbandwidth_dl, | |
| escaped_account, escaped_ip, | |
| escaped_port, escaped_peer_ip, | |
| escaped_decimal_ip)) != NULL) { | |
| const unsigned long q = (unsigned long) strtoul(bandwidth_dl, NULL, 10); | |
| if (q > 0UL) { | |
| result->throttling_bandwidth_dl = q * 1024UL; | |
| result->throttling_dl_changed = 1; | |
| } | |
| } | |
| #endif | |
| result->slow_tilde_expansion = !tildexp; | |
| result->auth_ok = -result->auth_ok; | |
| bye: | |
| if (committed == 0) { | |
| (void) pw_mysql_simplequery(id_sql_server, MYSQL_TRANSACTION_END); | |
| } | |
| if (id_sql_server != NULL) { | |
| mysql_close(id_sql_server); | |
| } | |
| free((void *) spwd); | |
| if (uid != sql_default_uid) { | |
| free((void *) uid); | |
| } | |
| if (gid != sql_default_gid) { | |
| free((void *) gid); | |
| } | |
| free((void *) dir); | |
| #ifdef QUOTAS | |
| free((void *) sqta_fs); | |
| free((void *) sqta_sz); | |
| #endif | |
| #ifdef RATIOS | |
| free((void *) ratio_ul); | |
| free((void *) ratio_dl); | |
| #endif | |
| #ifdef THROTTLING | |
| free((void *) bandwidth_ul); | |
| free((void *) bandwidth_dl); | |
| #endif | |
| free((void *) escaped_account); | |
| free((void *) escaped_ip); | |
| free((void *) escaped_port); | |
| free((void *) escaped_peer_ip); | |
| free((void *) escaped_decimal_ip); | |
| } | |
| void pw_mysql_parse(const char * const file) | |
| { | |
| if (generic_parser(file, mysql_config_keywords) != 0) { | |
| die(421, LOG_ERR, MSG_CONF_ERR ": " MSG_ILLEGAL_CONFIG_FILE_SQL ": %s", | |
| file); | |
| } | |
| if (server == NULL && socket_path == NULL) { | |
| die(421, LOG_ERR, MSG_SQL_MISSING_SERVER); | |
| } | |
| if (server != NULL && socket_path != NULL) { | |
| free(socket_path); | |
| socket_path = NULL; | |
| } | |
| if (tildexp_s != NULL) { | |
| if ((tildexp = atoi(tildexp_s)) < 0) { | |
| tildexp = 0; | |
| } | |
| free(tildexp_s); | |
| tildexp_s = NULL; | |
| } | |
| if (port_s != NULL) { | |
| port = atoi(port_s); | |
| if (port <= 0 || port > 65535) { | |
| port = MYSQL_DEFAULT_PORT; | |
| } | |
| free(port_s); | |
| port_s = NULL; | |
| } | |
| } | |
| #define ZFREE(X) do { free(X); (X) = NULL; } while (0) | |
| void pw_mysql_exit(void) | |
| { | |
| ZFREE(server); | |
| ZFREE(port_s); | |
| port = -1; | |
| ZFREE(socket_path); | |
| ZFREE(user); | |
| ZFREE(pw); | |
| ZFREE(db); | |
| ZFREE(crypto); | |
| ZFREE(transactions); | |
| ZFREE(sqlreq_getpw); | |
| ZFREE(sqlreq_getuid); | |
| ZFREE(sql_default_uid); | |
| ZFREE(sqlreq_getgid); | |
| ZFREE(sql_default_gid); | |
| ZFREE(sqlreq_getdir); | |
| #ifdef QUOTAS | |
| ZFREE(sqlreq_getqta_fs); | |
| ZFREE(sqlreq_getqta_sz); | |
| #endif | |
| #ifdef RATIOS | |
| ZFREE(sqlreq_getratio_ul); | |
| ZFREE(sqlreq_getratio_dl); | |
| #endif | |
| #ifdef THROTTLING | |
| ZFREE(sqlreq_getbandwidth_ul); | |
| ZFREE(sqlreq_getbandwidth_dl); | |
| #endif | |
| } | |
| #else | |
| extern signed char v6ready; | |
| #endif |