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; }
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; }