예제 #1
0
static int mavis_send_in(mavis_ctx * mcx, av_ctx ** ac)
{
    struct passwd *pw;
    char *t, *u, *p, *m;
    char buf[1024];

    t = av_get(*ac, AV_A_TYPE);
    u = av_get(*ac, AV_A_USER);
    p = av_get(*ac, AV_A_PASSWORD);

    if (strcmp(t, AV_V_TYPE_FTP))
	return MAVIS_DOWN;

    /* no VHOST support yet */
    m = av_get(*ac, AV_A_FTP_ANONYMOUS);
    if (m && !strcmp(m, AV_V_BOOL_TRUE))
	return MAVIS_DOWN;

    if (mcx->honour_ftpusers && !valid_user(mcx, u)) {
	av_set(*ac, AV_A_COMMENT, "user found in ftpusers file");
	av_set(*ac, AV_A_RESULT, AV_V_RESULT_FAIL);
	return MAVIS_FINAL;
    }
#ifdef HAVE_SHADOWPWD
    if (!mcx->passwordfile) {
	struct spwd *spw;
	uid_t uid;

	uid = geteuid();
	seteuid(0);
	spw = getspnam(u);
	seteuid(uid);

	if (!spw)
	    return MAVIS_DOWN;

	if (strcmp(spw->sp_pwdp, mcx->crypt(p, spw->sp_pwdp))) {
	    av_set(*ac, AV_A_COMMENT, "password mismatch");
	    av_unset(*ac, AV_A_DBPASSWORD);
	} else
	    av_set(*ac, AV_A_DBPASSWORD, p);
	pw = getpwnam(u);

	if (!pw) {
	    av_set(*ac, AV_A_COMMENT, "user not found in password file");
	    av_set(*ac, AV_A_RESULT, AV_V_RESULT_FAIL);
	    return MAVIS_FINAL;
	}
    } else
#endif				/* HAVE_SHADOWPWD */
    {
	int f;

	f = open(mcx->passwordfile, O_RDONLY);
	if (f < 0) {
	    av_set(*ac, AV_A_COMMENT, "error opening password file");
	    av_set(*ac, AV_A_RESULT, AV_V_RESULT_ERROR);
	    return MAVIS_DOWN;
	}
	pw = get_pwent(mcx, f, u);
	close(f);

	if (!pw)
	    return MAVIS_DOWN;
#undef crypt			/* may be set by openssl include stuff */
	if (strcmp(pw->pw_passwd, mcx->crypt(p, pw->pw_passwd))) {
	    av_set(*ac, AV_A_COMMENT, "password mismatch");
	    av_unset(*ac, AV_A_DBPASSWORD);
	} else
	    av_set(*ac, AV_A_DBPASSWORD, p);
    }

    if (mcx->require_valid_shell && (!pw->pw_shell || !valid_shell(mcx, pw->pw_shell))) {
	av_set(*ac, AV_A_COMMENT, "invalid shell");
	av_set(*ac, AV_A_RESULT, AV_V_RESULT_FAIL);
	return MAVIS_FINAL;
    }
    if (!pw->pw_dir) {
	av_set(*ac, AV_A_COMMENT, "home dir not set");
	av_set(*ac, AV_A_RESULT, AV_V_RESULT_FAIL);
	return MAVIS_FINAL;
    }

    av_setf(*ac, AV_A_UID, "%lu", (u_long) pw->pw_uid);
    av_setf(*ac, AV_A_GID, "%lu", (u_long) pw->pw_gid);

    /* attempt to get supplemental groups */

    av_set(*ac, AV_A_GIDS, groups_getlist(pw->pw_name, pw->pw_gid, buf, sizeof(buf)));

    if (mcx->ftp_chroot) {
	char *tp = strstr(pw->pw_dir, "/./");
	if (tp) {
	    *tp = 0;
	    av_set(*ac, AV_A_HOME, tp + 2);
	} else
	    av_set(*ac, AV_A_HOME, "/");
	av_set(*ac, AV_A_ROOT, pw->pw_dir);
    } else {
	av_set(*ac, AV_A_HOME, pw->pw_dir);
	av_set(*ac, AV_A_ROOT, "/");
    }

    if (mcx->lookup_sslusers)
	lookup_ssluser(mcx, *ac, u);

    return MAVIS_FINAL;
}
예제 #2
0
static int mavis_send_in(mavis_ctx * mcx, av_ctx ** ac)
{
    struct passwd *pw;
    char *t, *u, *p, *m;
    uid_t uid;
    int res;

    t = av_get(*ac, AV_A_TYPE);
    u = av_get(*ac, AV_A_USER);
    p = av_get(*ac, AV_A_PASSWORD);

    if (strcmp(t, AV_V_TYPE_FTP))
	return MAVIS_DOWN;

/* no VHOST support yet */
    m = av_get(*ac, AV_A_FTP_ANONYMOUS);
    if (m && !strcmp(m, AV_V_BOOL_TRUE))
	return MAVIS_DOWN;

    if (!(pw = getpwnam(u)))
	return MAVIS_DOWN;

    if (!pw->pw_dir) {
	av_set(*ac, AV_A_COMMENT, "home dir not set");
	av_set(*ac, AV_A_RESULT, AV_V_RESULT_FAIL);
	return MAVIS_FINAL;
    }

    uid = geteuid();
    seteuid(0);
    res = check_auth(mcx, u, p);
    seteuid(uid);

    /* The PAM routines may have spoiled our logging identity. */
    logopen();

    if (res) {
	char buf[1024];

	av_set(*ac, AV_A_DBPASSWORD, p);

	av_setf(*ac, AV_A_UID, "%lu", (u_long) pw->pw_uid);
	av_setf(*ac, AV_A_GID, "%lu", (u_long) pw->pw_gid);

	/* attempt to get supplemental groups */

	av_set(*ac, AV_A_GIDS, groups_getlist(pw->pw_name, pw->pw_gid, buf, sizeof(buf)));

	if (mcx->ftp_chroot) {
	    t = strstr(pw->pw_dir, "/./");
	    if (t) {
		*t = 0;
		av_set(*ac, AV_A_HOME, t + 2);
	    } else
		av_set(*ac, AV_A_HOME, "/");
	    av_set(*ac, AV_A_ROOT, pw->pw_dir);
	} else {
	    av_set(*ac, AV_A_HOME, pw->pw_dir);
	    av_set(*ac, AV_A_ROOT, "/");
	}
    } else
	av_set(*ac, AV_A_RESULT, AV_V_RESULT_FAIL);
    return MAVIS_FINAL;
}