authenticate.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 303 行

C
303
字号
#ifndef lintstatic	char	*sccsid = "@(#)authenticate.c	4.2	(ULTRIX)	11/15/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1989 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * Modification history: * * 14-Nov-90 D. Long *	Fixed erroneous use of access(2).  Access is now determined *	by dbm_open(3). *//* * authenticate_user - a routine to verify a user's password. */#include <unistd.h>#include <sys/errno.h>#include <pwd.h>#include <sys/svcinfo.h>#include <ttyent.h>#include "auth.h"static AUTHORIZATION *auth;static char authorization_db[] = AUTHORIZATION_DB;static char empty[] = "";/* * Function to determine if an authenticated user actually has login access * on the specified tty device.  If the "tty" argument is NULL then only * general login capability will be tested for.  Function returns zero on * success and the negative autherr on failure.  Errno will be set with the * coarse error status on error. */static int term_access(pwd, tty)register struct passwd *pwd;char *tty;{/* * If auth record for user verify they have login capability in authmask. */	if(auth)		if(!(auth->a_authmask & A_LOGIN)) {			errno = EPERM;			return -A_ENOLOGIN;		}/* * If checking tty information and user is root make sure they are specifying * a secure tty. */	if(tty && pwd->pw_uid == 0) {		struct ttyent *t;		char *ttyn;		extern char *rindex();/* * Get basename of tty device. */		if((ttyn=rindex(tty, '/')))			ttyn++;		else			ttyn = tty;/* * Get ttys entry for tty device. */		if(!(t=getttynam(ttyn))) {			errno = EPERM;			return -A_EOPENLINE;		}/* * Make sure it supports privileged login. */		if(!(t->ty_status&TTY_SECURE)) {			errno = EPERM;			return -A_EOPENLINE;		}	}	return 0;}/* * Library function to authenticate a user.  The supplied password is * verified against the applicable user password base on the current * I&A security level.  Password expiration information is also examined * if it is available.  If the tty argument is supplied the user is also * tested for login access to the system in general and on the specified * line in particular.  On success the function returns the number of failed * authentication attempts since the last successful one (or zero if this * feature is not enabled).  On failure it returns minus autherr and sets * errno: * *	Reason				errno		return * *	Passwd is wrong			EPERM		A_EBADPASS *	SEC_LEVEL > BSD and no auth *	     record was found		EINVAL		- *	Password expired		EPERM		A_ESOFTEXP/A_EHARDEXP *	Unable to initialize auth info	ENOSYS		- *	Unable to read auth data base	EACCES		- * * The following errors could also occur when a non-NULL tty argument is * supplied: * *	Reason				errno		return * *	Account is disabled in ADB	EPERM		A_ENOLOGIN *	Privileged account and tty was *	     not found in /etc/ttys	EPERM		A_EOPENLINE *	Privileged account and tty is not *	     marked secure in /etc/ttys	EPERM		A_EOPENLINE */int authenticate_user(pwd, passwd, tty)register struct passwd *pwd;char *passwd, *tty;{	extern AUTHORIZATION *getauthuid();	extern char *crypt(), *crypt16();	extern long time();	struct svcinfo *svcinfo;	int sec_level, i;	char *pp, *(*fp)();	auth = (AUTHORIZATION *) 0;	if(!pwd) {		errno = EINVAL;		return -EINVAL;	}/* * Get the service and security configuration. */	if(!(svcinfo=getsvc())) {		errno = ENOSYS;		return -ENOSYS;	}	sec_level = svcinfo->svcauth.seclevel;/* * Get the password based on the I&A security mode. */	switch(sec_level) {	case SEC_BSD:/* * Password is always in /etc/passwd (compatability). */		pp = pwd->pw_passwd;		fp = crypt;		break;	case SEC_UPGRADE:		if(!(auth=getauthuid(pwd->pw_uid))) {			if(errno == 0)				errno = EINVAL;			else if(errno == ENOENT)				errno = ENOSYS;			return -errno;		}/* * If the passwd file has an "*" in the password field then the password has * already been moved into the auth data base. */		if(!strcmp(pwd->pw_passwd, "*")) {			pp = auth->a_password;			fp = crypt16;		} else {/* * Otherwise the password is still in /etc/passwd. */			pp = pwd->pw_passwd;			fp = crypt;		}		break;	case SEC_ENHANCED:/* * The password is always in the auth data base. */		if(!(auth=getauthuid(pwd->pw_uid))) {			if(errno == 0)				errno = EINVAL;			else if(errno == ENOENT)				errno = ENOSYS;			return -errno;		}		pp = auth->a_password;		fp = crypt16;		break;	default:/* * Unsupported security level. */		errno = ENOSYS;		return -ENOSYS;	}/* * Assume NULL pointer means NULL string. */	if(!pp)		pp = empty;	if(!passwd)		passwd = empty;/* * If non-empty password supplied when there is no password for the account * detect it here.  This is a special case because crypt(3) always returns * an empty string when the salt is an empty string leading to erroneous * authentications. */	if(!*pp && *passwd) {/* * Increment failed authentication counter (if not served remotely). */		if(auth && svc_lastlookup == SVC_LOCAL) {			auth->a_fail_count++;			storeauthent(auth);			endauthent();		}		errno = EPERM;		return -A_EBADPASS;	}/* * Compare passwords. */	if(strcmp((*fp)(passwd, pp), pp)) {/* * Increment failed authentication counter (if not served remotely). */		if(auth && svc_lastlookup == SVC_LOCAL) {			auth->a_fail_count++;			storeauthent(auth);			endauthent();		}		errno = EPERM;		return -A_EBADPASS;	}/* * If tty argument supplied check login access on the specified line. */	if(tty) {		int i;		if(!*tty)			tty = NULL;		if((i=term_access(pwd, tty)) < 0)			return i;	}	i = 0;/* * If auth information present check the password expiration times. */	if(auth) {		extern long time();		long now, expiration;		if(auth->a_pw_maxexp) {			now = time((long *) 0);			expiration = auth->a_pass_mod + auth->a_pw_maxexp;			if(now > expiration) {				endauthent();/* * Set hard or soft expiration error code as approriate. */				errno = EPERM;				if(now > expiration + svcinfo->svcauth.softexp)					return -A_EHARDEXP;				else					return -A_ESOFTEXP;			}		}/* * Not expired. */		i = auth->a_fail_count;/* * Clear the authentication fail count. */		if(i && svc_lastlookup == SVC_LOCAL) {			auth->a_fail_count = 0;			storeauthent(auth);		}		endauthent();	}/* * Return the number of failed attempts since last successful authentication * (or zero if feature not enabled). */	return i;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?