This is pop_pass.c in view mode; [Download] [Up]
/* * 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] = '\0'; 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] = '\0'; 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 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 == '\0') || 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) #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 == '\0') || 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 == '\0') || 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 == '\0') || (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) == '\0')) { 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 == '\0')) { 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 == '\0')) { 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 == '\0') || 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 #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 */ /* pw_encrypt() ?? */ if ((pw->pw_passwd == NULL) || (*pw->pw_passwd == '\0') || (strcmp(crypt(p->pop_parm[1], pw->pw_passwd), pw->pw_passwd) && strcmp(pw_encrypt(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 /* LINUX */ #else /* NOT AUTH */ 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 == '\0') || 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 */ /* * pass: Obtain the user password from a POP client */ #ifdef SECURENISPLUS /* AUTH gets defined in rpc/... */ # ifdef AUTH # undef AUTH # endif # 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 = '\0'; #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] = '\0'; if (! getsecretkey(net_name, secretkey, p->pop_parm[1]) || *secretkey == '\0') { sleep(SLEEP_SECONDS); return (pop_msg(p,POP_FAILURE, pwerrmsg, p->user)); } key_setsecret(secretkey); memset(secretkey, '\0', 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)); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.