#ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #if 0 /* FRITZBOX */ #ifdef HAVE_SHADOW_H #include #endif #endif /* FRITZBOX */ #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #include #include #include typedef void (*sighandler_t)(int); #include "usermap.h" #include "logincontrol.h" /* LoginControlIsAllowed LoginControlWrongPassword LoginControlPasswordOk */ #include "extern.h" /* If name is "ftp" or "anonymous", the name is not in PATH_FTPUSERS, and ftp account exists, set cred, then just return. If account doesn't exist, ask for passwd anyway. Otherwise, check user requesting login privileges. Disallow anyone who does not have a standard shell as returned by getusershell(). Disallow anyone mentioned in the file PATH_FTPUSERS to allow people such as root and uucp to be avoided. */ int auth_user (const char *display_name, const char *real_name, struct credentials *pcred) { #if 1 // FRITZBOX char map_buffer[64]; real_name = usermap_mapuser(real_name, map_buffer, sizeof(map_buffer)); #endif pcred->guest = 0; switch (pcred->auth_type) { #ifdef WITH_PAM case AUTH_TYPE_PAM: #error WITH_PAM not supported (name may be 0) return pam_user (name, pcred); #endif #ifdef WITH_KERBEROS case AUTH_TYPE_KERBEROS: return -1; #endif #ifdef WITH_KERBEROS5 case AUTH_TYPE_KERBEROS5: return -1; #endif #ifdef WITH_OPIE case AUTH_TYPE_OPIE: return -1; #endif case AUTH_TYPE_PASSWD: default: { size_t len; if (pcred->message) free (pcred->message); len = 64 + strlen (display_name); pcred->message = malloc (len); if (pcred->message == NULL) return -1; #if 0 /* FRITZBOX */ /* check for anonymous logging */ if (strcmp (real_name, "ftp") == 0 || strcmp (real_name, "anonymous") == 0) { int err = 0; if (checkuser (PATH_FTPUSERS , "ftp") || checkuser (PATH_FTPUSERS, "anonymous")) { snprintf (pcred->message, len, "User %s access denied.", display_name); err = 1; } else if (sgetcred ("ftp", pcred) == 0) { pcred->guest = 1; strcpy (pcred->message, "Guest login ok, type your name as password."); } else { snprintf (pcred->message, len, "User %s unknown.", display_name); err = 1; } return err; } #endif int failed = 1; if (pcred->access_from_internet) { size_t rnlen = strlen(real_name) + 3 + 1; char * real_name_internet = malloc(rnlen); if (real_name_internet) { sprintf(real_name_internet, "%sint", real_name); failed = sgetcred (display_name, real_name_internet, pcred); free(real_name_internet); } } else { failed = sgetcred (display_name, real_name, pcred); } if (!failed) { if (!LoginControlIsAllowed(display_name)) { //blockiert snprintf (pcred->message, len, "User %s access denied.", display_name); return 1; } #if 0 /* FRITZBOX */ const char *cp; const char *shell; /* Check if the shell is allowed */ shell = pcred->shell; if (shell == NULL || *shell == 0) shell = PATH_BSHELL; setusershell (); while ((cp = getusershell ()) != NULL) if (strcmp (cp, shell) == 0) break; endusershell (); if (cp == NULL || checkuser (PATH_FTPUSERS, real_name)) { sprintf (pcred->message, "User %s access denied.", display_name); return 1; } #endif } else { free(pcred->message); pcred->message = 0; return 1; } #if 1 /* FRITZBOX */ pcred->dochroot = 0; #else pcred->dochroot = checkuser(PATH_FTPCHROOT, pcred->name); #endif snprintf (pcred->message, len, "Password required for %s.", display_name); return 0; } } /* switch (auth_type) */ return -1; } // check if GUI should behave as near as possible like a firmware without boxusers (pre PERF12) int IsPrePERF12CompatibilityMode(void) { return usermap_is_compatibility_mode(); } int IsSkipAuthenticationFromHomenetwork(/*OUT*/char **pskip_username) { return usermap_is_skip_auth_from_homenetwork(pskip_username); } static int CheckPassword(const char *passwd, const char *cred_passwd) { char *xpasswd; const char *salt = cred_passwd; /* Try to authenticate the user. */ if (cred_passwd == NULL || *cred_passwd == '\0') return 1; /* Failed. */ #if 1 /* FRITZBOX */ if (0 == strcmp(cred_passwd, "any")) { return 0; /* OK, no PW check */ } #endif xpasswd = CRYPT (passwd, salt); int fail = (!xpasswd || strcmp (xpasswd, cred_passwd) != 0); return fail; } int auth_pass (const char *passwd, struct credentials *pcred) { switch (pcred->auth_type) { #ifdef WITH_PAM case AUTH_TYPE_PAM: return pam_pass (passwd, pcred); #endif #ifdef WITH_KERBEROS case AUTH_TYPE_KERBEROS: return -1; #endif #ifdef WITH_KERBEROS5 case AUTH_TYPE_KERBEROS5: return -1; #endif #ifdef WITH_OPIE case AUTH_TYPE_OPIE: return -1; #endif case AUTH_TYPE_PASSWD: default: { int fail = CheckPassword(passwd, pcred->passwd); if (pcred->display_name) { if (fail) { // fail counter increment and ev. block futher logins for some time LoginControlWrongPassword(pcred->display_name, pcred->access_from_internet); } else { // fail counter reset LoginControlPasswordOk(pcred->display_name, pcred->access_from_internet); } } return fail; } } /* switch (auth_type) */ return -1; } int sgetcred (const char *display_name, const char *real_name, struct credentials *pcred) { struct passwd *p; p = getpwnam (real_name); if (p == NULL) return 1; if (pcred->name) free (pcred->name); if (pcred->display_name) free (pcred->display_name); if (pcred->passwd) free (pcred->passwd); if (pcred->homedir) free (pcred->homedir); if (pcred->rootdir) free (pcred->rootdir); if (pcred->shell) free (pcred->shell); #if 0 /* FRITZBOX - no shadow */ #if defined(HAVE_GETSPNAM) && defined(HAVE_SHADOW_H) if (p->pw_passwd == NULL || strlen (p->pw_passwd) == 1) { struct spwd *spw; setspent (); spw = getspnam (p->pw_name); if (spw != NULL) { time_t now; long today; now = time ((time_t *) 0); today = now / (60 * 60 * 24); if ((spw->sp_expire > 0 && spw->sp_expire < today) || (spw->sp_max > 0 && spw->sp_lstchg > 0 && (spw->sp_lstchg + spw->sp_max < today))) { /*reply (530, "Login expired."); */ p->pw_passwd = NULL; } else p->pw_passwd = spw->sp_pwdp; } endspent (); } #endif #endif /* FRITZBOX - no Shadow */ pcred->uid = p->pw_uid; pcred->gid = p->pw_gid; pcred->name = sgetsave (p->pw_name); pcred->display_name = sgetsave (display_name); pcred->passwd = sgetsave (p->pw_passwd); #if 1 // FRITZBOX pcred->rootdir = sgetsave ("/root-not-set"); pcred->homedir = sgetsave ("/home-not-set"); #else pcred->rootdir = sgetsave (p->pw_dir); pcred->homedir = sgetsave ("/"); #endif pcred->shell = sgetsave (p->pw_shell); return 0; }