📄 ftpd.c
字号:
if (login_attempts) { enable_signaling(); /* we can allow signals once again: kinch */ sleep((unsigned) login_attempts); } return;}/* Check if a user is in the file _PATH_FTPUSERS */int checkuser(char *name){ register FILE *fd; register char *p; char line[BUFSIZ]; if ((fd = fopen(_PATH_FTPUSERS, "r")) != NULL) { while (fgets(line, sizeof(line), fd) != NULL) if ((p = strchr(line, '\n')) != NULL) { *p = '\0'; if (line[0] == '#') continue; if (strcasecmp(line, name) == 0) { (void) fclose(fd); return (1); } } (void) fclose(fd); } return (0);}int denieduid(uid_t uid){ struct aclmember *entry = NULL; int which; char *ptr; struct passwd *pw; while (getaclentry("deny-uid", &entry)) { for (which = 0; (which < MAXARGS) && ARG[which]; which++) { if (!strcmp(ARG[which], "*")) return (1); if (ARG[which][0] == '%') { if ((ptr = strchr(ARG[which] + 1, '-')) == NULL) { if ((ptr = strchr(ARG[which] + 1, '+')) == NULL) { if (uid == strtoul(ARG[which] + 1, NULL, 0)) return (1); } else { *ptr++ = '\0'; if ((ARG[which][1] == '\0') || (uid >= strtoul(ARG[which] + 1, NULL, 0))) { *--ptr = '+'; return (1); } *--ptr = '+'; } } else { *ptr++ = '\0'; if (((ARG[which][1] == '\0') || (uid >= strtoul(ARG[which] + 1, NULL, 0))) && ((*ptr == '\0') || (uid <= strtoul(ptr, NULL, 0)))) { *--ptr = '-'; return (1); } *--ptr = '-'; } } else {#ifdef OTHER_PASSWD pw = bero_getpwnam(ARG[which], _path_passwd);#else pw = getpwnam(ARG[which]);#endif if (pw && (uid == pw->pw_uid)) return (1); } } } return (0);}int alloweduid(uid_t uid){ struct aclmember *entry = NULL; int which; char *ptr; struct passwd *pw; while (getaclentry("allow-uid", &entry)) { for (which = 0; (which < MAXARGS) && ARG[which]; which++) { if (!strcmp(ARG[which], "*")) return (1); if (ARG[which][0] == '%') { if ((ptr = strchr(ARG[which] + 1, '-')) == NULL) { if ((ptr = strchr(ARG[which] + 1, '+')) == NULL) { if (uid == strtoul(ARG[which] + 1, NULL, 0)) return (1); } else { *ptr++ = '\0'; if ((ARG[which][1] == '\0') || (uid >= strtoul(ARG[which] + 1, NULL, 0))) { *--ptr = '+'; return (1); } *--ptr = '+'; } } else { *ptr++ = '\0'; if (((ARG[which][1] == '\0') || (uid >= strtoul(ARG[which] + 1, NULL, 0))) && ((*ptr == '\0') || (uid <= strtoul(ptr, NULL, 0)))) { *--ptr = '-'; return (1); } *--ptr = '-'; } } else {#ifdef OTHER_PASSWD pw = bero_getpwnam(ARG[which], _path_passwd);#else pw = getpwnam(ARG[which]);#endif if (pw && (uid == pw->pw_uid)) return (1); } } } return (0);}int deniedgid(gid_t gid){ struct aclmember *entry = NULL; int which; char *ptr; struct group *grp; while (getaclentry("deny-gid", &entry)) { for (which = 0; (which < MAXARGS) && ARG[which]; which++) { if (!strcmp(ARG[which], "*")) return (1); if (ARG[which][0] == '%') { if ((ptr = strchr(ARG[which] + 1, '-')) == NULL) { if ((ptr = strchr(ARG[which] + 1, '+')) == NULL) { if (gid == strtoul(ARG[which] + 1, NULL, 0)) return (1); } else { *ptr++ = '\0'; if ((ARG[which][1] == '\0') || (gid >= strtoul(ARG[which] + 1, NULL, 0))) { *--ptr = '+'; return (1); } *--ptr = '+'; } } else { *ptr++ = '\0'; if (((ARG[which][1] == '\0') || (gid >= strtoul(ARG[which] + 1, NULL, 0))) && ((*ptr == '\0') || (gid <= strtoul(ptr, NULL, 0)))) { *--ptr = '-'; return (1); } *--ptr = '-'; } } else { grp = getgrnam(ARG[which]); if (grp && (gid == grp->gr_gid)) return (1); } } } return (0);}int allowedgid(gid_t gid){ struct aclmember *entry = NULL; int which; char *ptr; struct group *grp; while (getaclentry("allow-gid", &entry)) { for (which = 0; (which < MAXARGS) && ARG[which]; which++) { if (!strcmp(ARG[which], "*")) return (1); if (ARG[which][0] == '%') { if ((ptr = strchr(ARG[which] + 1, '-')) == NULL) { if ((ptr = strchr(ARG[which] + 1, '+')) == NULL) { if (gid == strtoul(ARG[which] + 1, NULL, 0)) return (1); } else { *ptr++ = '\0'; if ((ARG[which][1] == '\0') || (gid >= strtoul(ARG[which] + 1, NULL, 0))) { *--ptr = '+'; return (1); } *--ptr = '+'; } } else { *ptr++ = '\0'; if (((ARG[which][1] == '\0') || (gid >= strtoul(ARG[which] + 1, NULL, 0))) && ((*ptr == '\0') || (gid <= strtoul(ptr, NULL, 0)))) { *--ptr = '-'; return (1); } *--ptr = '-'; } } else { grp = getgrnam(ARG[which]); if (grp && (gid == grp->gr_gid)) return (1); } } } return (0);}/* Terminate login as previous user, if any, resetting state; used when USER * command is given or login fails. */void end_login(void){ delay_signaling(); /* we can't allow any signals while euid==0: kinch */ (void) seteuid((uid_t) 0); if (logged_in) if (wtmp_logging) wu_logwtmp(ttyline, pw->pw_name, remotehost, 0); pw = NULL;#ifdef AFS_AUTH ktc_ForgetAllTokens();#endif logged_in = 0; anonymous = 0; guest = 0;}int validate_eaddr(char *eaddr){ int i, host, state; for (i = host = state = 0; eaddr[i] != '\0'; i++) { switch (eaddr[i]) { case '.': if (!host) return 0; if (state == 2) state = 3; host = 0; break; case '@': if (!host || state > 1 || !strncasecmp("ftp", eaddr + i - host, host)) return 0; state = 2; host = 0; break; case '!': case '%': if (!host || state > 1) return 0; state = 1; host = 0; break; case '-': break; default: host++; } } if (((state == 3) && host > 1) || ((state == 2) && !host) || ((state == 1) && host > 1)) return 1; else return 0;}#if defined(VIRTUAL) && defined(CLOSED_VIRTUAL_SERVER)static int AllowVirtualUser(const char *username){ struct aclmember *entry = NULL; int which; while (getaclentry("virtual", &entry)) if (ARG0 && hostmatch(ARG0, virtual_address, virtual_hostname) && ARG1 && !strcasecmp(ARG1, "allow")) for (which = 2; (which < MAXARGS) && ARG[which]; which++) if (!strcasecmp(username, ARG[which]) || !strcmp("*", ARG[which])) return (1); return (0);}static int DenyVirtualUser(const char *username){ struct aclmember *entry = NULL; int which; while (getaclentry("virtual", &entry)) if (ARG0 && hostmatch(ARG0, virtual_address, virtual_hostname) && ARG1 && !strcasecmp(ARG1, "deny")) for (which = 2; (which < MAXARGS) && ARG[which]; which++) if (!strcasecmp(username, ARG[which]) || !strcmp("*", ARG[which])) return (1); return (0);}static int DenyVirtualAnonymous(void){ struct aclmember *entry = NULL; while (getaclentry("virtual", &entry)) if (ARG0 && hostmatch(ARG0, virtual_address, virtual_hostname) && ARG1 && !strcasecmp(ARG1, "private")) return (1); return (0);}#endifvoid pass(char *passwd){#if !defined(USE_PAM) || (defined(USE_PAM) && defined(OTHER_PASSWD)) char *xpasswd, *salt;#endif int passwarn = 0; int rval = 1;#ifdef SECUREOSF struct pr_passwd *pr; int crypt_alg = 0;#endif#ifdef BSD_AUTH extern int ext_auth; extern char *check_auth();#endif#ifdef ULTRIX_AUTH int numfails;#endif /* ULTRIX_AUTH */#ifdef HAS_PW_EXPIRE int set_expired = FALSE;#endif #ifdef AFS_AUTH char *reason;#endif /* AFS_AUTH */#ifdef DCE_AUTH sec_passwd_rec_t pwr; sec_login_handle_t lhdl; boolean32 rstpwd; sec_login_auth_src_t asrc; error_status_t status;#endif /* DCE_AUTH */ if (logged_in || askpasswd == 0) {#ifdef VERBOSE_ERROR_LOGING syslog(LOG_NOTICE, "FTP LOGIN REFUSED (PASS before USER) FROM %s", remoteident);#endif reply(503, "Login with USER first."); return; } askpasswd = 0; /* Disable lreply() if the first character of the password is '-' since * some hosts don't understand continuation messages and hang... */ if (*passwd == '-') dolreplies = 0; else dolreplies = 1;/* ******** REGULAR/GUEST USER PASSWORD PROCESSING ********** */ if (!anonymous) { /* "ftp" is only account allowed no password */#ifndef HELP_CRACKERS if (DenyLoginAfterPassword) { pr_mesg(530, DelayedMessageFile); reply(530, "Login incorrect."); acl_remove(); pw = NULL; if (++login_attempts >= lgi_failure_threshold) { syslog(LOG_NOTICE, "repeated login failures from %s", remoteident); exit(0); } return; }#endif if (*passwd == '-') passwd++;#ifdef USE_PAM#ifdef OTHER_PASSWD if (use_pam) {#endif /* PAM authentication * If PAM authenticates a user we know nothing about on the local * system, use the generic guest account credentials. We should make * this somehow a configurable item somewhere; later more on that. * * For now assume the guest (not anonymous) identity, so the site * admins can still differentiate between the truw anonymous user and * a little bit more special ones. Otherwise he wouldn't go the extra * mile to have a different user database, right? * --gaftonc */ if (pam_check_pass(the_user, passwd)) { rval = 0; if (pw == NULL) { /* assume guest account identity */ pw = sgetpwnam("ftp"); anonymous = 0; guest = 1; /* even go as far as... */ if (pw != NULL && pw->pw_name != NULL) { free(pw->pw_name); pw->pw_name = sgetsave(the_user); } } }#ifdef OTHER_PASSWD } else {#endif#endif /* USE_PAM */#if !defined(USE_PAM) || (defined(USE_PAM) && defined(OTHER_PASSWD))#ifdef BSD_AUTH if (ext_auth) { if ((salt = check_auth(the_user, passwd))) { reply(530, "%s", salt);#ifdef LOG_FAILED /* 27-Apr-93 EHK/BM */ syslog(LOG_INFO, "failed login from %s", remoteident);#endif /* LOG_FAILED */ acl_remove(); pw = NULL; if (++login_attempts >= lgi_failure_threshold) { syslog(LOG_NOTICE, "repeated login failures from %s", remoteident); exit(0); } return; } } else {#endif /* BSD_AUTH */ *guestpw = '\0'; if (pw == NULL) salt = "xx"; else#ifndef OPIE salt = pw->pw_passwd;#ifdef SECUREOSF if ((pr = getprpwnam(pw->pw_name)) != NULL) { if (pr->uflg.fg_newcrypt) crypt_alg = pr->ufld.fd_newcrypt; else if (pr->sflg.fg_newcrypt) crypt_alg = pr->sfld.fd_newcrypt; else crypt_alg = 0; } else crypt_alg = 0; xpasswd = dispcrypt(passwd, salt, crypt_alg);#elif defined(SecureWare) || defined(HPUX_10_TRUSTED) xpasswd = bigcrypt(passwd, salt);#elif defined(KERBEROS) xpasswd = crypt16(passwd, salt);#elif defined(SKEY)#ifndef __NetBSD__ xpasswd = skey_crypt(passwd, salt, pw, pwok); pwok = 0;#else if ((pw != NULL) && (pw->pw_name != NULL) && skey_haskey(pw->pw_name) == 0 && skey_passcheck(pw->pw_name, passwd) != -1) xpasswd = pw->pw_passwd; else xpasswd = crypt(passwd, salt);#endif#else /* !SKEY */ xpasswd = crypt(passwd, salt);#endif /* SKEY */#else /* OPIE */ if (!opieverify(&opiestate, passwd)) rval = 0; xpasswd = crypt(passwd, pw->pw_passwd);#endif /* OPIE */#ifdef ULTRIX_AUTH if ((numfails = ultrix_check_pass(passwd, xpasswd)) >= 0) {#else if (pw != NULL) {#ifdef AFS_AUTH if (strcmp(pw->pw_passwd, "X") == 0) if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION | KA_USERAUTH_DOSETPAG, pw->pw_name, "", 0, passwd, 0, 0, 0, &reason) == 0) rval = 0; else printf("230-AFS: %s", reason); else#endif /* AFS_AUTH */ /* The strcmp does not catch null passwords! */#ifdef HAS_PW_EXPIRE if(pw->pw_expire != NULL) { if(pw->pw_expire && time(NULL) >= pw->pw_expire) { set_expired = TRUE; } }#endif if (*pw->pw_passwd != '\0' &&#ifdef HAS_PW_EXPIRE !set_expired &&#endif strcmp(xpasswd, pw->pw_passwd
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -