pop_pass.c
上传用户:dayuan858
上传日期:2007-01-04
资源大小:194k
文件大小:16k
- /*
- * Copyright (c) 1989 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
- /*
- * Copyright (c) 1997 by Qualcomm Incorporated.
- */
- #include <config.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <string.h>
- #if HAVE_STRINGS_H
- # include <strings.h>
- #endif
- #include <pwd.h>
- #include "popper.h"
- #define SLEEP_SECONDS 10
- /* This error message is vague on purpose to help reduce help improve
- security at the inconvience of administrators and users */
- char *pwerrmsg = "Password supplied for "%s" is incorrect.";
- #ifdef NONAUTHFILE
- checknonauthfile(user)
- char *user;
- {
- char buf[MAXUSERNAMELEN+1];
- FILE *fp;
- char cool = 0;
- if ((fp = fopen(NONAUTHFILE, "r")) != NULL) {
- while (fgets(buf, MAXUSERNAMELEN+1, fp)) {
- buf[strlen(buf) -1] = ' ';
- if (!strcmp(buf, user)) {
- fclose(fp);
- return(-1);
- }
- }
- fclose(fp);
- }
- return(0);
- }
- #endif
- #ifdef AUTHFILE
- checkauthfile(user)
- char *user;
- {
- char buf[MAXUSERNAMELEN+1];
- FILE *fp;
- char cool = 0;
- if ((fp = fopen(AUTHFILE, "r")) != NULL) {
- while (fgets(buf, MAXUSERNAMELEN+1, fp)) {
- buf[strlen(buf) -1] = ' ';
- if (!strcmp(buf, user)) {
- fclose(fp);
- return(0);
- }
- }
- fclose(fp);
- }
- return(-1);
- }
- #endif
- int auth_user_kerberos (p, pw)
- POP * p;
- struct passwd *pw;
- {
- #ifdef KERBEROS
- char lrealm[REALM_SZ];
- int status;
- struct passwd *pwp;
-
- if ((status = krb_get_lrealm(lrealm,1)) == KFAILURE) {
- pop_log(p, LOG_WARNING, "%s: (%s.%s@%s) %s", p->client, kdata.pname,
- kdata.pinst, kdata.prealm, krb_err_txt[status]);
- return(pop_msg(p,POP_FAILURE,
- "Kerberos error: "%s".", krb_err_txt[status]));
- }
- # ifdef KUSEROK
- if (kuserok(&kdata, p->user)) {
- pop_log(p, LOG_WARNING, "%s: (%s.%s@%s): not in %s's ACL.",
- p->client, kdata.pname, kdata.pinst, kdata.prealm, p->user);
- return(pop_msg(p,POP_FAILURE, "Not in %s's ACL.", p->user));
- }
- # else
- if (strcmp(kdata.prealm,lrealm)) {
- pop_log(p, LOG_WARNING, "%s: (%s.%s@%s) realm not accepted.",
- p->client, kdata.pname, kdata.pinst, kdata.prealm);
- return(pop_msg(p,POP_FAILURE,
- "Kerberos realm "%s" not accepted.", kdata.prealm));
- }
- if (strcmp(kdata.pinst,"")) {
- pop_log(p, LOG_WARNING, "%s: (%s.%s@%s) instance not accepted.",
- p->client, kdata.pname, kdata.pinst, kdata.prealm);
- return(pop_msg(p,POP_FAILURE,
- "Must use null Kerberos(tm) instance - "%s.%s" not accepted.",
- kdata.pname, kdata.pinst));
- }
- # endif /* KUSEROK */
- return(POP_SUCCESS);
- #else /* Kerberos not defined */
- return(pop_log(p, LOG_WARNING,
- "Kerberos failure: The popper has not been compiled with -DKERBEROS"));
- #endif /* KERBEROS */
- }
- #ifdef AUTH_SPECIAL
- char *crypt();
- #if defined(SUNOS4) && !defined(ISC)
- #include <sys/label.h>
- #include <sys/audit.h>
- #include <pwdadj.h>
- static int
- auth_user(p, pw)
- POP * p;
- struct passwd *pw;
- {
- struct passwd_adjunct *pwadj;
- /* Look for the user in the shadow password file */
- if ((pwadj = getpwanam(p->user)) == NULL) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE,
- "(shadow) Password supplied for "%s" is empty.",p->user));
- } else {
- pw->pw_passwd = (char *)strdup(pwadj->pwa_passwd);
- }
- /* We don't accept connections from users with null passwords */
- /* Compare the supplied password with the password file entry */
- if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == ' ') ||
- strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE,pwerrmsg, p->user));
- }
- return(POP_SUCCESS);
- }
- #endif /* SUNOS4 */
- #if defined(SOLARIS2) || defined(AUX) || defined(UXPDS)
- #include <shadow.h>
- static int
- auth_user(p, pw)
- POP * p;
- struct passwd *pw;
- {
- register struct spwd * pwd;
- long today;
- /* Look for the user in the shadow password file */
- if ((pwd = getspnam(p->user)) == NULL) {
- if (!strcmp(pw->pw_passwd, "x")) { /* This my be a YP entry */
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- } else {
- today = (long)time((time_t *)NULL)/24/60/60;
- /* Check for expiration date */
- if (pwd->sp_expire > 0 && today > pwd->sp_expire) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE,""%s": account expired.",p->user));
- }
- /* Check if password is valid */
- if (pwd->sp_max > 0 && today > pwd->sp_lstchg+pwd->sp_max) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE,""%s": account expired.",p->user));
- }
- pw->pw_passwd = (char *)strdup(pwd->sp_pwdp);
- endspent();
- }
- /* We don't accept connections from users with null passwords */
- /* Compare the supplied password with the password file entry */
- if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == ' ') ||
- strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p, POP_FAILURE, pwerrmsg, p->user));
- }
- return(POP_SUCCESS);
- }
- #endif /* SOLARIS2 || AUX */
- #if defined(PTX) || defined(ISC)
- #include <shadow.h>
- static int
- auth_user(p, pw)
- POP * p;
- struct passwd *pw;
- {
- register struct spwd * pwd;
- long today;
- /* Look for the user in the shadow password file */
- if ((pwd = getspnam(p->user)) == NULL) {
- if (!strcmp(pw->pw_passwd, "x")) { /* This my be a YP entry */
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- } else {
- pw->pw_passwd = (char *)strdup(pwd->sp_pwdp);
- }
- /* We don't accept connections from users with null passwords */
- /* Compare the supplied password with the password file entry */
- if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == ' ') ||
- strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- return(POP_SUCCESS);
- }
- #endif /* PTX */
- #if defined(POPSCO) || defined(HPUX10)
- #ifdef POPSCO
- # include <sys/security.h>
- # include <sys/audit.h>
- #else
- # include <hpsecurity.h>
- #endif
- #include <prot.h>
- #define PASSWD(p) p->ufld.fd_encrypt
- static int
- auth_user(p, pw)
- POP * p;
- struct passwd *pw;
- {
- register struct pr_passwd *pr;
- if ((pr = getprpwnam(p->user)) == NULL) {
- if (!strcmp(pw->pw_passwd, "x")) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- /* We don't accept connections from users with null passwords */
- if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == ' ') ||
- (strcmp(bigcrypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) &&
- strcmp(crypt (p->pop_parm[1], pw->pw_passwd), pw->pw_passwd))) {
- sleep(SLEEP_SECONDS);
- return(pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- } else {
- /* We don't accept connections from users with null passwords */
- /* Compare the supplied password with the password file entry */
- if ((PASSWD(pr) == NULL) || (*PASSWD(pr) == ' ')) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
-
- if (strcmp(bigcrypt(p->pop_parm[1], PASSWD(pr)), PASSWD(pr)) &&
- strcmp(crypt(p->pop_parm[1], PASSWD(pr)), PASSWD(pr))) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- }
- return(POP_SUCCESS);
- }
- #endif /* POPSCO || HPUX10 */
- #ifdef ULTRIX
- #include <auth.h>
- static int
- auth_user(p, pw)
- struct passwd * pw;
- POP * p;
- {
- AUTHORIZATION *auth, *getauthuid();
- if ((auth = getauthuid(pw->pw_uid)) == NULL) {
- if (!strcmp(pw->pw_passwd, "x")) { /* This my be a YP entry */
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- } else {
- pw->pw_passwd = (char *)strdup(auth->a_password);
- }
- /* We don't accept connections from users with null passwords */
- /* Compare the supplied password with the password file entry */
- if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == ' ')) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- if (strcmp(crypt16(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) &&
- strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- return(POP_SUCCESS);
- }
- #endif /* ULTRIX */
- #ifdef OSF1
- #include <sys/types.h>
- #include <sys/security.h>
- #include <prot.h>
- #define PASSWD(p) (p->ufld.fd_encrypt)
- static int
- auth_user(p, pw)
- POP * p;
- struct passwd *pw;
- {
- register struct pr_passwd *pr;
- if ((pr = getprpwnam(p->user)) == NULL) {
- if (!strcmp(pw->pw_passwd, "x")) { /* This my be a YP entry */
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- } else {
- pw->pw_passwd = (char *)strdup(PASSWD(pr));
- }
- /* We don't accept connections from users with null passwords */
- /* Compare the supplied password with the password file entry */
- if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == ' ')) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- if (strcmp(bigcrypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) &&
- strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- return(POP_SUCCESS);
- }
- #endif /* OSF1 */
- #ifdef UNIXWARE
- #include <shadow.h>
- static int
- auth_user(p, pw)
- struct passwd * pw;
- POP * p;
- {
- register struct spwd * pwd;
- long today;
- /* Look for the user in the shadow password file */
- if ((pwd = getspnam(p->user)) == NULL) {
- if (!strcmp(pw->pw_passwd, "x")) { /* This my be a YP entry */
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- } else {
- today = (long)time((time_t *)NULL)/24/60/60;
- /* Check for expiration date */
- if (pwd->sp_expire > 0 && today > pwd->sp_expire) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE,""%s": account expired.",p->user));
- }
- /* Check if password is valid */
- if (pwd->sp_max > 0 && today > pwd->sp_lstchg+pwd->sp_max) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE,""%s": account expired.",p->user));
- }
- pw->pw_passwd = (char *)strdup(pwd->sp_pwdp);
- endspent();
- }
- /* We don't accept connections from users with null passwords */
- /* Compare the supplied password with the password file entry */
- if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == ' ') ||
- strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- return(POP_SUCCESS);
- }
- #endif /* UNIXWARE */
- #ifdef LINUX
- #ifdef HAVE_SHADOW_H
- #include <shadow.h>
- #endif
-
- static int
- auth_user(p, pw)
- POP * p;
- struct passwd *pw;
- {
- register struct spwd * pwd;
- long today;
- /* Look for the user in the shadow password file */
- if ((pwd = getspnam(p->user)) == NULL) {
- if (!strcmp(pw->pw_passwd, "x")) { /* This my be a YP entry */
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- } else {
- today = (long)time((time_t *)NULL)/24/60/60;
- /* Check for expiration date */
- if (pwd->sp_expire > 0 && today > pwd->sp_expire) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE,""%s": account expired.",p->user));
- }
- /* Check if password is valid */
- if (pwd->sp_max > 0 && today > pwd->sp_lstchg+pwd->sp_max) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE,""%s": account expired.",p->user));
- }
- pw->pw_passwd = (char *)strdup(pwd->sp_pwdp);
- endspent();
- }
- /* We don't accept connections from users with null passwords */
- /* Compare the supplied password with the password file entry */
- /* pw_encrypt() ?? */
- if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == ' ') ||
- (strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)
- #ifdef HAVE_PW_ENCRYPT
- && strcmp(pw_encrypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)
- #endif
- )){
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- return(POP_SUCCESS);
- }
- #endif /* LINUX */
- #else /* NOT AUTH_SPECIAL */
- char *crypt();
- static int
- auth_user(p, pw)
- POP * p;
- struct passwd * pw;
- {
- /* We don't accept connections from users with null passwords */
- /* Compare the supplied password with the password file entry */
- if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == ' ') ||
- strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd)) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- return(POP_SUCCESS);
- }
- #endif /* AUTH_SPECIAL */
- /*
- * pass: Obtain the user password from a POP client
- */
- #ifdef SECURENISPLUS
- # include <rpc/rpc.h>
- # include <rpc/key_prot.h>
- #endif
- int pop_pass (p)
- POP * p;
- {
- struct passwd pw, *pwp;
- #ifdef CHECK_SHELL
- char *getusershell();
- void endusershell();
- char *shell;
- char *cp;
- int shellvalid;
- #endif
- #ifdef SECURENISPLUS
- UID_T uid_save;
- char net_name[MAXNETNAMELEN],
- secretkey[HEXKEYBYTES + 1];
- *secretkey = ' ';
- #endif
- #ifdef NONAUTHFILE
- /* Is the user not authorized to use POP? */
- if (checknonauthfile(p->user) != 0) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- #endif
- #ifdef AUTHFILE
- /* Is the user authorized to use POP? */
- if (checkauthfile(p->user) != 0) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- #endif
- /* Look for the user in the password file */
- if ((pwp = getpwnam(p->user)) == NULL) {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- pw = *pwp;
- #ifdef SECURENISPLUS
- /* we must do this keyserv stuff (as well as auth_user()!) as the user */
- uid_save = geteuid();
- seteuid(pw.pw_uid);
- /* see if DES keys are already known to the keyserv(1m) */
- if (! key_secretkey_is_set()) {
- /* keys are not known, so we must get the DES keys
- and register with the keyserv(1m) */
- getnetname(net_name);
- if (getpublickey(net_name, secretkey)) {
- if (strlen(p->pop_parm[1]) > 8) (p->pop_parm[1])[8] = ' ';
- if (! getsecretkey(net_name, secretkey, p->pop_parm[1]) ||
- *secretkey == ' ') {
- sleep(SLEEP_SECONDS);
- return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user));
- }
- key_setsecret(secretkey);
- memset(secretkey, ' ', sizeof(secretkey));
- } else {
- /* if there are no keys defined, we assume that password entry
- either resides in /etc/shadow or "root" has access to the
- corresponding NIS+ entry */
- seteuid(0);
- }
- }
- #endif
- #ifdef BLOCK_UID
- if (pw.pw_uid <= BLOCK_UID)
- return (pop_msg(p,POP_FAILURE,
- "Access is blocked for UIDs below %d", BLOCK_UID));
- #endif
- #ifdef CHECK_SHELL
- /* Disallow anyone who does not have a standard shell as returned by
- * getusershell(), unless the sys admin has included the wildcard
- * shell in /etc/shells. (default wildcard - /POPPER/ANY/SHELL)
- */
- if ((shell = pw.pw_shell) == NULL || *shell == 0)
- /* You can default the shell, but I don't think it's a good idea */
- /* shell = "/usr/bin/sh"; */
- return(pop_msg(p, POP_FAILURE, "No user shell defined"));
-
- for (shellvalid = 0; !shellvalid && ((cp = getusershell()) != NULL);)
- if (!strcmp(cp, WILDCARD_SHELL) || !strcmp(cp, shell))
- shellvalid = 1;
- endusershell();
- if (!shellvalid)
- return(pop_msg(p, POP_FAILURE, ""%s": shell not found.", p->user));
- #endif
- if ((p->kerberos ? auth_user_kerberos(p, pw) : auth_user(p, pwp))
- != POP_SUCCESS) {
- pop_log(p,POP_PRIORITY,"Failed attempted login to %s from host %s",
- p->user, p->client);
- return(POP_FAILURE);
- }
- #ifdef SECURENISPLUS
- seteuid(uid_save);
- #endif
- /* Make a temporary copy of the user's maildrop */
- /* and set the group and user id */
- /* and get information about the maildrop */
- if (pop_dropcopy(p, &pw) != POP_SUCCESS) return (POP_FAILURE);
- /* Initialize the last-message-accessed number */
- p->last_msg = 0;
- /* Authorization completed successfully */
- return (pop_msg (p,POP_SUCCESS,
- "%s has %d message%s (%d octets).",
- p->user,p->msg_count, p->msg_count == 1 ? "" : "s", p->drop_size));
- }