示例#1
0
static const char *uptime(void)
{
#ifdef __FreeBSD__
    struct timeval boottime;
    time_t now;
    int mib[2];
    size_t size;
    time_t u;
    static char buf[1025];

    (void)time(&now);

    mib[0] = CTL_KERN;
    mib[1] = KERN_BOOTTIME;
    size = sizeof(boottime);
    if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 &&
        boottime.tv_sec != 0) {
        u = now - boottime.tv_sec;
        if (u > 60)
            u += 30;

        if (SNCHECK(snprintf(buf, sizeof buf, "%lu days, %lu:%02lu:%02lu",
                             u / 86400UL, u / 3600UL % 24UL,
                             u / 60UL % 60UL, u % 60UL),
                    sizeof buf)) {
            _exit(EXIT_FAILURE);
        }
    }
    return buf;
#else
    int f;
    ssize_t r;
    unsigned long u;
    static char buf[1025];

    if ((f = open("/proc/uptime", O_RDONLY)) == -1) {
        return "?";
    }
    while ((r = read(f, buf, sizeof buf - 1U)) < (ssize_t) 0 && errno == EINTR);
    if (r <= (ssize_t) 0) {
        close(f);
        return "?";
    }
    close(f);
    u = strtoul(buf, NULL, 10);
    if (SNCHECK(snprintf(buf, sizeof buf, "%lu days, %lu:%02lu:%02lu",
                         u / 86400UL, u / 3600UL % 24UL,
                         u / 60UL % 60UL, u % 60UL),
                sizeof buf)) {
        _exit(EXIT_FAILURE);
    }
    return buf;
#endif
}
示例#2
0
static LDAPMessage *pw_ldap_uid_search(LDAP * const ld,
                                       const char *uid,
                                       char *attrs[])
{
    char *alloca_filter;
    size_t uid_size;
    size_t filter_size;
    int rc;
    LDAPMessage *res;

    if (uid == NULL || *uid == 0) {
        return NULL;
    }
    uid_size = strlen(uid);
    if (uid_size > MAX_LDAP_UID_LENGTH) {
        return NULL;
    }
    filter_size = strlen(ldap_filter) + uid_size + (size_t) 1U;
    if ((alloca_filter = ALLOCA(filter_size)) == NULL) {
        return NULL;
    }
    if (SNCHECK(snprintf(alloca_filter, filter_size, ldap_filter, uid),
        filter_size)) {
        ALLOCA_FREE(alloca_filter);
        return NULL;
    }
    rc = ldap_search_s(ld, base, LDAP_SCOPE_SUBTREE,
                       alloca_filter, attrs, 0, &res);
    ALLOCA_FREE(alloca_filter);
    if (rc != LDAP_SUCCESS) {
        return NULL;
    }

    return res;
}
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='******' password='******'"
        
    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;
}
示例#4
0
static int altlog_writexfer_w3c(const int upload,
                                const char * const filename,
                                const off_t size,
                                const double duration)
{
    /*
     * <date> <time> <ip> "[]sent" <file> "226" <user>
     * date time c-ip cs-method cs-uri-stem sc-status cs-username
     */

    struct tm *tm;
    struct tm gmt;
    const char *host_ = *host != 0 ? host : "-";
    const char *account_ = *account != 0 ? account : "-";
    char *alloca_line;
    char *quoted_filename;
    time_t now;
    size_t line_size;

    (void) duration;
    if ((now = time(NULL)) == (time_t) -1 ||
        (tm = localtime(&now)) == NULL ||
        tm->tm_mon > 11 || tm->tm_mon < 0) {
        return -1;
    }
    gmt = *gmtime(&now);
    if ((quoted_filename = urlencode(filename)) == NULL) {
        return -1;
    }
    line_size = (sizeof "13-04-1975 12:34:56 " - 1U) +
        strlen(host_) + 1U + (sizeof "[]created" - 1U) + 1U +
        strlen(quoted_filename) + 1U + (sizeof "226" - 1U) +
        strlen(account_) + 1U + 42U + 1U /* \n */ + 1U;

    if ((alloca_line = ALLOCA(line_size)) == NULL) {
        return -1;
    }
    if (!SNCHECK(snprintf(alloca_line, line_size,
                          "%d-%02d-%02d %02d:%02d:%02d %s []%s %s 226 %s %llu\n",
                          gmt.tm_year + 1900, gmt.tm_mon + 1, gmt.tm_mday,
                          gmt.tm_hour, gmt.tm_min, gmt.tm_sec,
                          host_, (upload != 0 ? "created" : "sent"),
                          quoted_filename,
                          account, (unsigned long long) size), line_size)) {
        altlog_write(alloca_line);
    }
    if (quoted_filename != filename) {
        free(quoted_filename);
    }
    ALLOCA_FREE(alloca_line);

    return 0;
}
示例#5
0
static void newenv_uo(const char * const var, const unsigned int val)
{
    size_t s;
    char *v;

    s = strlen(var) + (size_t) 8U;
    if ((v = malloc(s)) == NULL) {
        return;
    }
    if (SNCHECK(snprintf(v, s, "%s=%o", var, val), s)) {
        free(v);
        return;
    }
    putenv(v);
}
示例#6
0
static void newenv_str(const char * const var, const char * const str)
{
    size_t s;
    char *v;

    if (str == NULL || *str == 0) {
        return;
    }
    s = strlen(var) + strlen(str) + (size_t) 2U;
    if ((v = malloc(s)) == NULL) {
        return;
    }
    if (SNCHECK(snprintf(v, s, "%s=%s", var, str), s)) {
        free(v);
        return;
    }
    putenv(v);
}
示例#7
0
static char *checkvirtual(char *path)
{
    static char buf[PATH_MAX + 1];
    char *path_pnt;

    if (path == NULL || *path == '/' ||
        (path_pnt = strstr(path, ":/")) == NULL) {
        return path;
    }
    *path_pnt = 0;
    if (SNCHECK(snprintf(buf, sizeof buf, VHOST_PATH "/%s%s",
                         path, path_pnt + 1), sizeof buf)) {
        /* Better avoid processing than risking a security flaw */
        return NULL;
    }

    return buf;
}
示例#8
0
void ftpwho_unlinksbfile(const pid_t pid)
{
    size_t sbfile_size;
    char *sbfile;
    
    sbfile_size = sizeof SCOREBOARD_PATH - 1U + 1U +
        sizeof SCOREBOARD_PREFIX - 1U + 8U + 1U;
        
    if ((sbfile = ALLOCA(sbfile_size)) == NULL) {
        return;
    }
    if (SNCHECK(snprintf(sbfile, sbfile_size, 
                         SCOREBOARD_PATH "/" SCOREBOARD_PREFIX "%08lu",
                         (unsigned long) pid), sbfile_size)) {
        ALLOCA_FREE(sbfile);
        return;
    }    
    (void) unlink(sbfile);
    ALLOCA_FREE(sbfile);
}
示例#9
0
static int altlog_writexfer_stats(const int upload,
                                  const char * const filename,
                                  const off_t size,
                                  const double duration)
{
    /*
     * <date> <start.pid> <user> <ip> <u/d> <size> <duration> <file>
     */

    const char *host_ = *host != 0 ? host : "-";
    const char *account_ = *account != 0 ? account : "-";
    char *alloca_line;
    size_t line_size;

    line_size = 16U /* now */ + 1U + 16U /* start */ + 1U /* . */ +
        16U /* pid */ + 1U + strlen(account_) + 1U + strlen(host_) + 1U +
        1U /* U/D */ + 1U + 20U /* size */ + 1U + 16U /* duration */ +
        strlen(filename) + 1U /* \n */ + 1U;
    if ((alloca_line = ALLOCA(line_size)) == NULL) {
        return -1;
    }
    if (!SNCHECK(snprintf(alloca_line, line_size,
                          "%llu %llx.%lx %s %s %c %llu %lu %s\n",
                          (unsigned long long) time(NULL),
                          (unsigned long long) session_start_time,
                          (unsigned long) getpid(),
                          account_, host_,
                          upload != 0 ? 'U' : 'D',
                          (unsigned long long) size,
                          (unsigned long) (duration + 0.5),
                          filename), line_size)) {
        altlog_write(alloca_line);
    }

    ALLOCA_FREE(alloca_line);

    return 0;
}
示例#10
0
static void updatepidfile(void)
{
    char buf[42];
    size_t buf_len;
    int fd;

    if (SNCHECK(snprintf(buf, sizeof buf, "%lu\n",
                         (unsigned long) getpid()), sizeof buf)) {
        return;
    }
    if (unlink(uploadscript_pid_file) != 0 && errno != ENOENT) {
        return;
    }
    if ((fd = open(uploadscript_pid_file, O_CREAT | O_WRONLY | O_TRUNC |
                   O_NOFOLLOW, (mode_t) 0644)) == -1) {
        return;
    }
    buf_len = strlen(buf);
    if (safe_write(fd, buf, buf_len, -1) != (ssize_t) buf_len) {
        (void) ftruncate(fd, (off_t) 0);
    }
    close(fd);
}
示例#11
0
int altlog_write_w3c_header(void)
{
    time_t now;
    struct tm *tm;
    struct tm gmt;
    char *alloca_line;
    size_t line_size;

    if ((now = time(NULL)) == (time_t) -1 ||
        (tm = localtime(&now)) == NULL ||
        tm->tm_mon > 11 || tm->tm_mon < 0) {
        return -1;
    }
    gmt = *gmtime(&now);
    line_size = sizeof "#Date: 001975-04-13 12:34:56\n";   /* be year-999999 compliant :) */
    if ((alloca_line = ALLOCA(line_size)) == NULL) {
        return -1;
    }

    altlog_write("#Software: Pure-FTPd " VERSION "\n");
    altlog_write("#Version: 1.0\n");

    if (!SNCHECK(snprintf(alloca_line, line_size,
                          "#Date: %04d-%02d-%02d %02d:%02d:%02d\n",
                          gmt.tm_year + 1900, gmt.tm_mon + 1, gmt.tm_mday,
                          gmt.tm_hour, gmt.tm_min, gmt.tm_sec),
                          line_size)) {
        altlog_write(alloca_line);
    }

    altlog_write("#Fields: date time c-ip cs-method cs-uri-stem sc-status cs-username sc-bytes\n");

    ALLOCA_FREE(alloca_line);

    return 0;
}
示例#12
0
static int altlog_writexfer_xferlog(const int upload,
                    const char * const filename,
                    const off_t size,
                    const double duration)
{
    char date[sizeof "Mon Apr 13 12:34:56 1975"];
    struct tm *tm;
    char *alloca_line;
    const char *host_ = *host != 0 ? host : "-";
    const char *account_ = *account != 0 ? account : "-";
    char *quoted_filename;
    size_t filename_idx;
    time_t now;
    size_t line_size;
    size_t filename_size;
    char c;

    if ((now = time(NULL)) == (time_t) -1 ||
        (tm = localtime(&now)) == NULL ||
        tm->tm_mon > 11 || tm->tm_mon < 0 ||
        tm->tm_wday > 6 || tm->tm_wday < 0) {
        return -1;
    }
    if (SNCHECK(snprintf(date, sizeof date,
                         "%s %s %02d %02d:%02d:%02d %d",
                         week_days[tm->tm_wday], months[tm->tm_mon],
                         tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
                         tm->tm_year + 1900), sizeof date)) {
        return -1;
    }
    if ((filename_idx = strlen(filename)) <= (size_t) 0U) {
        return -1;
    }
    filename_size = filename_idx + (size_t) 1U;
    if ((quoted_filename = ALLOCA(filename_size)) == NULL) {
        return -1;
    }

    quoted_filename[filename_idx] = 0;
    do {
        filename_idx--;
        c = filename[filename_idx];
        if (isspace((unsigned char) c) || ISCTRLCODE(c)) {
            c = '_';
        }
        quoted_filename[filename_idx] = c;
    } while (filename_idx > (size_t) 0U);

    line_size = (sizeof date - 1U) + (sizeof " " - 1U) +
        (size_t) 16U /* duration */ + (sizeof " " - 1U) +
        strlen(host_) + (sizeof " " - 1U) +
        (size_t) 20U /* size */ + (sizeof " " - 1U) +
        (filename_size - 1U) + (sizeof " " - 1U) +
        (size_t) 1U /* type */ + (sizeof " _ " - 1U) +
        (size_t) 1U /* direction */ + (sizeof " " - 1U) +
        (size_t) 1U /* anonymous */ + (sizeof " " - 1U) +
        strlen(account_) + (sizeof " ftp 1 * c\n" - 1U) + (size_t) 1U;
    if ((alloca_line = ALLOCA(line_size)) == NULL) {
        ALLOCA_FREE(quoted_filename);
        return -1;
    }
    if (!SNCHECK(snprintf(alloca_line, line_size,
                          "%s %lu %s %llu %s %c _ %c %c %s ftp 1 * c\n",
                          date, (unsigned long) (duration + 0.5),
                          host_, (unsigned long long) size,
                          quoted_filename,
                          type == 1 ? 'a' : 'b',
                          upload != 0 ? 'i' : 'o',
                          loggedin != 0 ? 'r' : 'a',
                          account_), line_size)) {
        altlog_write(alloca_line);
    }
    ALLOCA_FREE(quoted_filename);
    ALLOCA_FREE(alloca_line);

    return 0;
}
示例#13
0
static int altlog_writexfer_clf(const int upload,
                                const char * const filename,
                                const off_t size)
{
    char date[sizeof "13/Apr/1975:12:34:56 +0100"];
    struct tm *tm;
    char *alloca_line;
    const char *host_ = *host != 0 ? host : "-";
    const char *account_ = *account != 0 ? account : "-";
    char *quoted_filename;
    time_t now;
    long diff;
    int sign;
    size_t line_size;

    if ((now = time(NULL)) == (time_t) -1 ||
        (tm = localtime(&now)) == NULL ||
        tm->tm_mon > 11 || tm->tm_mon < 0) {
        return -1;
    }
# ifdef HAVE_STRUCT_TM_TM_GMTOFF
    diff = -(tm->tm_gmtoff) / 60L;
# elif defined(HAVE_SCALAR_TIMEZONE)
    diff = -(timezone) / 60L;
# else
    {
        struct tm gmt;
        struct tm *t;
        int days, hours, minutes;

        gmt = *gmtime(&now);
        t = localtime(&now);
        days = t->tm_yday - gmt.tm_yday;
        hours = ((days < -1 ? 24 : 1 < days ? -24 : days * 24)
                 + t->tm_hour - gmt.tm_hour);
        minutes = hours * 60 + t->tm_min - gmt.tm_min;
        diff = -minutes;
    }
# endif
    if (diff > 0L) {
        sign = '+';
    } else {
        sign = '-';
        diff = -diff;
    }

    if (SNCHECK(snprintf(date, sizeof date,
                         "%02d/%s/%d:%02d:%02d:%02d %c%02ld%02ld",
                         tm->tm_mday, months[tm->tm_mon], tm->tm_year + 1900,
                         tm->tm_hour, tm->tm_min, tm->tm_sec,
                         sign, diff / 60L, diff % 60L), sizeof date)) {
        return -1;
    }
    if ((quoted_filename = urlencode(filename)) == NULL) {
        return -1;
    }
    line_size = strlen(host_) + (sizeof " - " - 1U) + strlen(account_) +
        (sizeof " [" - 1U) + (sizeof date - 1U) + (sizeof "] \"" - 1U) +
        3U /* GET / PUT */ + (sizeof " " - 1U) + strlen(quoted_filename) +
        (sizeof "\" 200 18446744073709551616\n" - 1U) + 1U;
    if ((alloca_line = ALLOCA(line_size)) == NULL) {
        return -1;
    }
    if (!SNCHECK(snprintf(alloca_line, line_size,
                          "%s - %s [%s] \"%s %s\" 200 %llu\n",
                          host_, account_, date,
                          upload == 0 ? "GET" : "PUT", quoted_filename,
                          (unsigned long long) size), line_size)) {
        altlog_write(alloca_line);
    }
    if (quoted_filename != filename) {
        free(quoted_filename);
    }
    ALLOCA_FREE(alloca_line);

    return 0;
}
示例#14
0
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 */
    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;    
    char *scrambled_password = NULL;
    int committed = 1;
    int crypto_crypt = 0, crypto_plain = 0, crypto_md5 = 0, crypto_md5sha1 = 0; /* TRICK */
    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_pgsql_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 = (decimal_ip_raw[0] << 24) | 
            (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_pgsql_connect(&id_sql_server) != 0) {
        goto bye;
    }
    if ((escaped_account = 
         pw_pgsql_escape_string(account)) == NULL) {
        goto bye;
    }
    if ((escaped_ip = 
         pw_pgsql_escape_string(hbuf)) == NULL) {
        goto bye;
    }
    if ((escaped_port = 
         pw_pgsql_escape_string(pbuf)) == NULL) {
        goto bye;
    }
    if ((escaped_peer_ip = 
         pw_pgsql_escape_string(phbuf)) == NULL) {
        goto bye;
    }
    if ((escaped_decimal_ip = 
         pw_pgsql_escape_string(decimal_ip)) == NULL) {
        goto bye;
    }
    if (pw_pgsql_simplequery(id_sql_server, PGSQL_TRANSACTION_START) == 0) {
        committed = 0;
    }
    /*logfile(LOG_WARNING, "START AUTH 2 [%s]", sqlreq_getpw); */
    if ((spwd = pw_pgsql_getquery(id_sql_server, sqlreq_getpw,
                                  escaped_account, escaped_ip,
                                  escaped_port, escaped_peer_ip,
                                  escaped_decimal_ip)) == NULL) {
        goto bye;
    }
    /*logfile(LOG_WARNING, "START AUTH 3 [%s]", sqlreq_getuid);*/
    if (uid == NULL) {
        uid = pw_pgsql_getquery(id_sql_server, sqlreq_getuid,
                                escaped_account, escaped_ip, 
                                escaped_port, escaped_peer_ip,
                                escaped_decimal_ip);
    }
    if (uid == NULL) {
        goto bye;
    }
    /*logfile(LOG_WARNING, "START AUTH 4 [%s]", sqlreq_getgid);*/
    if (gid == NULL) {
        gid = pw_pgsql_getquery(id_sql_server, sqlreq_getgid,
                                escaped_account, escaped_ip,
                                escaped_port, escaped_peer_ip,
                                escaped_decimal_ip);
    }
    if (gid == NULL) {
        goto bye;
    }
    /*logfile(LOG_WARNING, "START AUTH 5 [%s]", sqlreq_getdir);*/
    if ((dir = pw_pgsql_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_crypt++;
        crypto_md5++;
    } else if (strcasecmp(crypto, PASSWD_SQL_CRYPT) == 0) {
        crypto_crypt++;
    } else if (strcasecmp(crypto, PASSWD_SQL_MD5) == 0) {
        crypto_md5++;
    } else if (strcasecmp(crypto, PASSWD_SQL_MD5SHA1) == 0) {
        crypto_md5sha1++;	/* TRICK */
    } else {                           /* default to plaintext */
        crypto_plain++;
    }
    if (crypto_crypt != 0) {
        register const char *crypted;
        
        if ((crypted = (const char *) crypt(password, spwd)) != NULL &&
            strcmp(crypted, spwd) == 0) {
            goto auth_ok;
        }
    }
    if (crypto_md5 != 0) {
        register const char *crypted;
        
        if ((crypted = (const char *) crypto_hash_md5(password, 1)) != NULL &&
            strcmp(crypted, spwd) == 0) {
            goto auth_ok;
        }
    }
    if (crypto_md5sha1 != 0) { /* TRICK */
        register const char *crypted;
        
        if ((crypted = (const char *) crypto_hash_sha1(password, 1)) != NULL ) {
            if ((crypted = (const char *) crypto_hash_md5(crypted, 1)) != NULL &&
                strcmp(crypted, spwd) == 0) {
                goto auth_ok;
            }
        }
    }
    if (crypto_plain != 0) {
        if (*password != 0 &&    /* refuse null cleartext passwords */
            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 || gr->gr_gid <= (gid_t) 0) {
            goto bye;
        }
        result->gid = gr->gr_gid;
    }    
    result->dir = dir;
    dir = NULL;    
#ifdef QUOTAS
    if ((sqta_fs = pw_pgsql_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_pgsql_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_pgsql_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_pgsql_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_pgsql_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_pgsql_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 = 1;
    result->auth_ok =- result->auth_ok;
    bye:
    if (committed == 0) {
        (void) pw_pgsql_simplequery(id_sql_server, PGSQL_TRANSACTION_END);
    }
    if (id_sql_server != NULL) {
        PQfinish(id_sql_server);
    }
    if (spwd != NULL) {
        free((void *) spwd);
    }
    if (uid != NULL) {
        free((void *) uid);
    }
    if (gid != NULL) {
        free((void *) gid);
    }
    if (dir != NULL) {
        free((void *) dir);
    }
    if (scrambled_password != NULL) {
        free(scrambled_password);
    }
#ifdef QUOTAS
    if (sqta_fs != NULL) {
        free((void *) sqta_fs);
    }
    if (sqta_sz != NULL) {
        free((void *) sqta_sz);
    }
#endif    
#ifdef RATIOS
    if (ratio_ul != NULL) {
        free((void *) ratio_ul);
    }
    if (ratio_dl != NULL) {
        free((void *) ratio_dl);
    }
#endif    
#ifdef THROTTLING
    if (bandwidth_ul != NULL) {
        free((void *) bandwidth_ul);
    }
    if (bandwidth_dl != NULL) {
        free((void *) bandwidth_dl);
    }
#endif    
    if (escaped_account != NULL) {
        free((void *) escaped_account);
    }
    if (escaped_ip != NULL) {
        free((void *) escaped_ip);
    }
    if (escaped_port != NULL) {
        free((void *) escaped_port);
    }
    if (escaped_peer_ip != NULL) {
        free((void *) escaped_peer_ip);
    }
    if (escaped_decimal_ip != NULL) {
        free((void *) escaped_decimal_ip);
    }    
}
示例#15
0
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;
    
	server = malloc(16);
	db = malloc(16);
	user = malloc(16);
	pw = malloc(16);
	snprintf( server, 10,"localhost");
	snprintf( db, 9,"fastprod");
	snprintf( user, 9,"fastprod");
	snprintf( pw, 9,"fastprod");
	
    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) {
			rprintf(FLOG,"ERR escaping\n");
        goto bye;
    }
	//rprintf(FLOG,"ERR conninfo:%s-%s\n",escaped_server,server);
    
#define PGSQL_CONNECT_FMTSTRING \
"host='%s' port='%d' dbname='%s' user='******' password='******'"
        
    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) {
			rprintf(FLOG,"ERR malloc(sizeof_conninfo)\n");
        goto bye;
    }
    if (SNCHECK(snprintf(conninfo, sizeof_conninfo,
                         PGSQL_CONNECT_FMTSTRING, 
                         server, port, db, user, pw), sizeof_conninfo)) {
			rprintf(FLOG,"ERR SNCHECK()\n");
        goto bye;
    }    
	//rprintf(FLOG,"ERR conninfo:%s\n",conninfo);
     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);
    }
			rprintf(FLOG,"ERR PQconnectdb\n");
        goto bye;
    }
    server_down = 0;
    ret = 0;
    
    bye:
    free(conninfo);
    free(escaped_server);
    free(escaped_db);
    free(escaped_user);
    free(escaped_pw);

    return ret;
}
示例#16
0
int ftpwho_initwho(void)
{
    int fd;
    size_t scoreboardfile_size;
    struct stat st;    
    
    shm_data_cur = NULL;
    if ((fd = open(SCOREBOARD_PATH, O_RDONLY | O_DIRECTORY)) == -1) {
        if (mkdir(SCOREBOARD_PATH, (mode_t) 0700) != 0) {
            return -1;
        }
    } else {        
        if (fstat(fd, &st) != 0 || !S_ISDIR(st.st_mode) ||
#ifdef NON_ROOT_FTP
            st.st_uid != geteuid()
#else
            st.st_uid != (uid_t) 0
#endif
            ) {
            close(fd);
            return -1;
        }
        if ((st.st_mode & 0777) != 0700) {
            if (fchmod(fd, 0700) != 0) {
                close(fd);
                return -1;
            }
        }
    }
    close(fd);
    scoreboardfile_size = sizeof SCOREBOARD_PATH - 1U + 1U +
        sizeof SCOREBOARD_PREFIX - 1U + 8U + 1U;
    if ((scoreboardfile = malloc(scoreboardfile_size)) == NULL) {
        return -1;
    }
    if (SNCHECK(snprintf(scoreboardfile, scoreboardfile_size, 
                         SCOREBOARD_PATH "/" SCOREBOARD_PREFIX "%08lu",
                         (unsigned long) getpid()), scoreboardfile_size)) {
        err:
        free(scoreboardfile);
        scoreboardfile = NULL;
        
        return -1;
    }
    /* 
     * Don't truncate: it's faster to reuse.
     * Don't check for any lock: we could get a deadlock.
     */
    if ((mmap_fd = open(scoreboardfile, 
                       O_RDWR | O_CREAT | O_NOFOLLOW, 0600)) == -1) {
        goto err;
    }
    if (fstat(mmap_fd, &st) != 0 || !S_ISREG(st.st_mode) ||
        (st.st_mode & 0600) != 0600 ||
#ifdef NON_ROOT_FTP
        st.st_uid != geteuid()
#else
        st.st_uid != (uid_t) 0
#endif
        ) {
        err2:
        close(mmap_fd);
        goto err;
    }
    if (lseek(mmap_fd, (off_t) (sizeof (FTPWhoEntry) - 1U), 
              SEEK_SET) == (off_t) -1) {
        goto err2;
    }
    while (write(mmap_fd, "", (size_t) 1U) < 0 && 
           (errno == EAGAIN || errno == EINTR));
    lock.l_whence = SEEK_SET;
    lock.l_start = (off_t) 0;
    lock.l_len = (off_t) 0;
    lock.l_pid = getpid();
    if ((shm_data_cur = (FTPWhoEntry *) mmap(NULL, sizeof (FTPWhoEntry),
                                             PROT_WRITE | PROT_READ,
                                             MAP_SHARED | MAP_FILE, 
                                             mmap_fd, (off_t) 0)) == NULL) {
        goto err2;
    }
    return 0;
}
示例#17
0
int quota_update(Quota *quota,
                 const long long files_add,
                 const long long size_add,
                 int *overflow)
{
    int fd;
    Quota old_quota = { 0ULL, 0ULL };
    Quota dummy_quota;
    struct flock lock;
    ssize_t readnb;
    int err = -1;
    char buf[84];
    char *bufpnt = buf;
    int dummy_overflow;
    ssize_t left = (ssize_t) (sizeof buf - 1U);
    size_t buf_len;

    if (hasquota() != 0 || chrooted == 0) {
        return -2;
    }
    if (overflow == NULL) {
        overflow = &dummy_overflow;
    }
    if (quota == NULL) {
        quota = &dummy_quota;
    }
    *overflow = 0;
    *quota = old_quota;
    if ((fd = open("/" QUOTA_FILE, O_RDWR | O_CREAT | O_NOFOLLOW,
                   (mode_t) 0600)) == -1) {
        return -1;
    }
    lock.l_whence = SEEK_SET;
    lock.l_start = (off_t) 0;
    lock.l_len = (off_t) 0;
    lock.l_pid = getpid();
    lock.l_type = F_WRLCK;
    while (fcntl(fd, F_SETLKW, &lock) < 0) {
        if (errno != EINTR) {
            goto byenounlock;
        }
    }
    do {
        while ((readnb = read(fd, bufpnt, left)) < (ssize_t) 0 &&
               errno == EINTR);
        if (readnb < (ssize_t) 0) {
            goto bye;
        }
        bufpnt += readnb;
        left -= readnb;
    } while (left > (ssize_t) 0 && readnb != (ssize_t) 0);
    *bufpnt = 0;
    if ((bufpnt = strchr(buf, ' ')) == NULL) {
        goto skipparse;
    }
    *bufpnt = 0;
    old_quota.files = quota->files = strtoull(buf, NULL, 10);
    old_quota.size = quota->size = strtoull(bufpnt + 1, NULL, 10);
    skipparse:
    if ((files_add | size_add) == 0LL) {
        goto okbye;
    }
    if (files_add < 0LL) {
        if (quota->files > (unsigned long long) -files_add) {
            quota->files -= (unsigned long long) (-files_add);
        } else {
            quota->files = 0ULL;
        }
    } else if (files_add >= 0LL) {
        quota->files += (unsigned long long) files_add;
        if (quota->files > user_quota_files) {
            *overflow = 1;
        }
    }
    if (size_add < 0LL) {
        if (quota->size > (unsigned long long) -size_add) {
            quota->size -= (unsigned long long) (-size_add);
        } else {
            quota->size = 0ULL;
        }
    } else if (size_add >= 0LL) {
        quota->size += size_add;
        if (quota->size > user_quota_size) {
            *overflow = 2;
        }
    }
    if ((old_quota.size != quota->size || old_quota.files != quota->files) &&
        !SNCHECK(snprintf(buf, sizeof buf, "%llu %llu\n",
                          quota->files, quota->size), sizeof buf) &&
        lseek(fd, (off_t) 0, SEEK_SET) != (off_t) -1 &&
        ftruncate(fd, (off_t) 0) == 0) {

        buf_len = strlen(buf);
        if (safe_write(fd, buf, buf_len, -1) != (ssize_t) buf_len) {
            (void) ftruncate(fd, (off_t) 0);
            goto bye;
        }
    }
    okbye:
    err = 0;

    bye:
    lock.l_type = F_UNLCK;
    while (fcntl(fd, F_SETLK, &lock) < 0 && errno == EINTR);
    byenounlock:
    close(fd);

    return err;
}
示例#18
0
void pw_extauth_check(AuthResult * const result,
                      const char *account, const char *password,
                      const struct sockaddr_storage * const sa,
                      const struct sockaddr_storage * const peer)
{
    int kindy = -1;
    int err;
    int tries = EXTAUTH_MAX_CONNECT_TRIES;
    ssize_t readnb;
    char *linepnt;
    char *crpoint;
    char sa_hbuf[NI_MAXHOST];
    char sa_port[NI_MAXSERV];
    char peer_hbuf[NI_MAXHOST];
    char line[4096];
    size_t line_len;
    
    result->auth_ok = 0;
    if (getnameinfo((struct sockaddr *) sa, STORAGE_LEN(*sa),
                    sa_hbuf, sizeof sa_hbuf,
                    sa_port, sizeof sa_port,
                    NI_NUMERICHOST | NI_NUMERICSERV) != 0 ||
        getnameinfo((struct sockaddr *) peer, STORAGE_LEN(*peer),
                    peer_hbuf, sizeof peer_hbuf,
                    NULL, (size_t) 0U,
                    NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
        return;
    }
    tryagain:
    if ((kindy = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        goto bye;
    }
    while ((err = connect(kindy, (struct sockaddr *) saddr, SUN_LEN(saddr)))
           != 0 && errno == EINTR);
    if (err != 0) {
        close(kindy);
        kindy = -1;
        if (tries > 0) {
            sleep(EXTAUTH_MAX_CONNECT_DELAY);
            tries--;
            goto tryagain;
        }
        goto bye;
    }
    if (SNCHECK(snprintf(line, sizeof line, 
                         EXTAUTH_CLIENT_ACCOUNT "%s\n"
                         EXTAUTH_CLIENT_PASSWORD "%s\n"
                         EXTAUTH_CLIENT_SA_HOST "%s\n"
                         EXTAUTH_CLIENT_SA_PORT "%s\n"
                         EXTAUTH_CLIENT_PEER_HOST "%s\n"
                         EXTAUTH_CLIENT_ENCRYPTED "%d\n"
                         EXTAUTH_CLIENT_END "\n",
                         account, password, sa_hbuf, sa_port, peer_hbuf,
                         tls_cnx != NULL),
                sizeof line)) {
        goto bye;
    }
    line_len = strlen(line);
    if (safe_write(kindy, line, line_len, -1) != (ssize_t) line_len) {
        goto bye;
    }    
    result->uid = (uid_t) 0;
    result->gid = (gid_t) 0;
    result->dir = NULL;
    result->slow_tilde_expansion = 1;    
    auth_finalized = 0;
    if ((readnb =
         safe_read_partial(kindy, line, sizeof line - 1U)) <= (ssize_t) 0) {
        goto bye;
    }
    line[readnb] = 0;    
    linepnt = line;
    while ((crpoint = strchr(linepnt, '\n')) != NULL) {
        const ExtauthCallBack *scanned;
        size_t keyword_len;

        *crpoint = 0;
        scanned = extauth_callbacks;
        while (scanned->keyword != NULL) {
            keyword_len = strlen(scanned->keyword);
            if (strncmp(scanned->keyword, linepnt, keyword_len) == 0) {
                scanned->func(linepnt + keyword_len, result);
                break;
            }
            scanned++;
        }
        linepnt = crpoint + 1;        
    }
    if (auth_finalized == 0 ||
        (result->auth_ok == 1 && 
         (result->uid <= (uid_t) 0 || result->gid <= (gid_t) 0 || 
          result->dir == NULL))) {
        result->auth_ok = -1;
    }
    bye:
    if (kindy != -1) {
        close(kindy);
    }
}