⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 login.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic  char    *sccsid = "@(#)login.c	4.6	(ULTRIX)	2/14/91";#endif lint/************************************************************************ *									* *		Copyright (c) 1986, 1987, 1988, 1989, 1990, 1991 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.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   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.	* *									* ************************************************************************//* *	$Source: /u1/usr/src/bin/RCS/login.c,v $ *	$Author: jg $ *	$Locker:  $ *	$Log:	login.c,v $ * *	14-Nov-90	dlong * Keep prompter alive for the whole time.  Prompter will be expected to * exit when the close-on-exec pipe to it is closed on shell startup.  This * allows all login errors, including shell-not-found to be reportable * through prompter.  It also allows prompter to signal login for * keyboard generated interrupts and provides an escape from a hard,intr * NFS home directory or mail spool file that has gone away. * *	26-Sep-90	wessex::lisa * Add two additional error messages to explain when a login is refused * because of an invalid or missing license PAK. Also extend time that * message is displayed for. * *	04-Sep-90	dlong * Don't hang with interrupts disabled if the HOME directory of mail spool * file is on an unavailable NFS partition. * *	17-Jul-89	jsd * Workaround ruserok() returning 0 on success, when it used to return 1. * *	19-Sep-89	dlong * Don't update auth entry (for fail count) if it doesn't reside on the local * machine. * *	22-Aug-89	dlong * Do an endauthent() before exec'ing password (to prevent retaining * an old cached entry), and before handing off to the user (to avoid * leaving them an open file descriptor for /etc/auth*).  Also, improve * error reporting since ERRORNXIT does not actually display the error * message.  Also, remove booby trap of closing all file descriptors after * having done a getauthuid() and a getpwnam() which might have intentionally * left open file decscriptors behind.  Also, only use one of T_ERROR or * T_RESULT in the audit record. * *	16-Aug-89	S. Logcher * Remove extraneous setpwent() and endpwent() calls from dodecnetlogin() * routine. * *	15-Aug-89	D. Long * Added prompter "-e" support.  Also, handle empty password better. * *	19-Jul-89 D. Long * Don't issue password expiration messages until after "Login succeeded" * message.  Otherwise the old prompter breaks.  Also, don't try and use the * UID as an audit ID.  Also, recognize the "e" option and ignore it.  Also, * fixed up some comments. * *	28-Jun-89 D. Long * Fixed problem logging in remotely in BSD mode.  Also, look for auth.h * in usr/include, not current directory. * *	15-May-89 Giles Atkinson * Convert login limits to use LMF * *	7/Jun/89	D. Long * Added security features for 4.0 * *	029 - Gary A. Gaudet. Fri Apr 21 21:57:43 EDT 1989 *		Added unbuffered stdin, cyphered name and password, *		and bzero buffer, for -P. * *	028 - Gary A. Gaudet. Mon Apr 17 14:37:31 EDT 1989 *		Added check for real root uid before using -P. * *	08/Jun/88	Mark Parenti * Changed signal handlers to void. * *	24/Mar/88	Tim Burke / Rich Hyde * Flush standard error after reporting an error.  Return success string to * prompter program to prevent reappearance of dialogue box on successful login. * *	29/Feb/88	Tim Burke / Rich Hyde * Flush output after reporting an error. * * 1.25 20/Jan/88	Mark Parenti * Change initialization of passwd structure to reflect changes made * for POSIX compliance. * *	07/Dec/87	Tim Burke / Rich Hyde * 1) Added a option -P <programname> that causes login to set it's *    standard input and output to be connected to the prompting program. *    This allows one to write a X based prompter that prompts for name and *    password and then ships that info back to login. * * 2) Added an option -C "string" to allow the system to specify a *    command to be run using the users shell.    It causes a (USER SHELL) -c *    "string" to be exec'ed.  This allows one to start a X based application *    but still allow normal logins, and [dr]logins to work. * *	08/Aug/87	Tim Burke * Look for LPASS8 in local mode word to preserve 8-bit mode as passed on * from getty(). * * 1.22 28/Jul/87	logcher * Changed doremotelogin() to call ruserok() in libc.a * * 1.20 02/Jun/87	logcher * In doremotelogin, when opening and reading ~user/.rhosts, seteuid * to that user uid and seteuid back after.  This avoids problems * when ~user is mounted remotely. * * 1.19 3/12/87		lp * Three times has to make it right! Finally fixed the decnet/telnet clash. * * 1.18 3/3/87		lp * Fixed the problem 1.15 problem abain (as 1.17 broke decnet). * *      2/25/87		Tim Burke * Allow setting of TERMIODISC if "termio" was specified in /etc/ttys. * * 1.17 2/12/87 	lp * Fixed a silly problem introduced in rev 1.15 (which broke telnet logins). *  * Rev 1.16 1/14/86	lp * Increased ahosts to 128 (from 32) as hostnames of the form * "washington.berekley.edu username" might be longer than 32 and * hence might not match. * * Revision 1.15 86/12/4	Tim Burke * A change to the dodecnetlogin routine to set proxy to -1 so that a prompt * for password will appear. * * Revision 1.14 86/8/8		Tim Burke * Inserted changes proposed by Peter Harbo of decnet.  These changes are * mainly in the dodecnetlogin routine to return -1 if username, but no * password has been received. * * Revision 1.13 86/6/24	Tim * Changed so that invalid rlogins and dlogins are handled similarly. * Inserted copyright notice. * * Revision 1.12 86/3/11	Robin * Made change to count logins in the kernel. * * Revision 1.11 86/2/5    10:05:00 robin * fixed problem that stopped erase from working if a second try * at logging in was made. * * Revision 1.8  85/10/22  10:30:00  was * add decnet support for remote login * * Revision 1.7  84/10/29  17:24:33  jg * fix problem with -p option.  Wasn't allowing user name, so getty * wasn't happy. *  * Revision 1.6  84/10/25  14:12:23  jg * Undid utmp changes.  Added -p flag to preserve environment passed * from getty. *  * Revision 1.5  84/10/01  09:28:38  jg * fix allocation bug that caused login to fail. *  * Revision 1.4  84/09/09  15:50:19  jg * fix bug introduced by environment change; was not doing rlogin right. *  * Revision 1.3  84/09/09  14:51:31  jg * fixed login not to destroy the environment set up by whomever is calling it. *  * Revision 1.2  84/09/01  11:39:08  jg * changes required by utmp.h changes. *  * Revision 1.1  84/04/20  01:07:13  root * Initial revision *  *//*static char *rcsid_login_c = "$Header: login.c,v 1.7 84/10/29 17:24:33 jg Exp $";static	char *sccsid = "@(#)login.c	4.34 (Berkeley) 84/05/07";*//* * login [ name ] * login -r hostname (for rlogind) * login -h hostname (for telnetd, etc.) */#define	NOPRIV#include <sys/param.h>#include <sys/quota.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/file.h>#include <sys/wait.h>#include <sys/types.h>#include <sys/sysinfo.h>#include <sys/utsname.h>#include <sys/ltatty.h>#ifndef	NOPRIV#include <sys/priv.h>#endif#include <sys/svcinfo.h>#include <fcntl.h>#include <sgtty.h>#include <utmp.h>#include <signal.h>#include <pwd.h>#include <grp.h>#include <stdio.h>#include <lastlog.h>#include <errno.h>#include <ttyent.h>#include <syslog.h>#include <limits.h>#include <lmf.h>#include <strings.h>#ifndef	NOAUDIT/* sample code to audit login's */#include <syscall.h>#include <sys/syscall.h>#include <sys/audit.h>#define LEN (SYSCALL_MASK_LEN+TRUSTED_MASK_LEN)#endif	NOAUDIT#include <auth.h>#include "proto.h"#ifdef AUTHEN#include <krb.h>#endif AUTHEN#define	SCMPN(a, b)	strncmp(a, b, sizeof(a))#define	SCPYN(a, b)	strncpy(a, b, sizeof(a))#define NMAX	sizeof(utmp.ut_name)#define	FALSE	0#define	TRUE	-1#ifndef	NOAUDITstatic char buf[LEN];static int i;#endif	NOAUDITchar	nolog[] =	"/etc/nologin";char	qlog[]  =	".hushlogin";char	maildir[40] =	"/usr/spool/mail/";char	lastlog[] =	"/usr/adm/lastlog";struct	passwd nouser = {"", "nope", -1, -1, -1, -1, -1, "", "", "", "" };struct	sgttyb ttyb;struct	utmp utmp;struct	ltattyi ltattyi;char	minusnam[16] = "-";char	*envinit[] =	{ 0 };		/* now set by setenv calls *//* * This bounds the time given to login.  We initialize it here * so it can be patched on machines where it's too small. */int	timeout = 240;char	term[64];struct	passwd *pwd, pwd_save;char *auth_db = AUTHORIZATION_DB;AUTHORIZATION *auth, *getauthuid();char	*strcat(), *rindex(), *index();void	timedout();char	*ttyname();char	*crypt16(), *crypt();char	*getpass();char	*stypeof();extern	char **environ;extern	int errno;struct	tchars tc = {	CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK};struct	ltchars ltc = {	CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT};int	rflag, dflag;int 	notty = FALSE;char	rusername[NMAX+1], lusername[NMAX+1];char	rpassword[NMAX+1];char	name[NMAX+1];char	*tty;static 	prompt_pid;static	eflag = 0;int	lastsend = -1;char	*pp;/* * Signal handler to just do an exit. */void exit_handler(sig, code, scp)int sig, code;struct sigconext *scp;{	exit(0);}/* * Function to send a message to the user, either through prompter * or the tty. */static sendreq(opcode, data)int opcode;char *data;{	REQ request;	register REQ *req = &request;	int i, length;	if(data)		length = strlen(data) + 1;	else		length = 0;/* * If using extended protocol send a packet out on stdout. */	if(eflag) {		SENDREQ(req, opcode, data, length);/* * Error messages are always acknowledged to provide a synchronous * user interface. */		if(opcode == ERROR) {			GETREQ(req, i);			if(req->opcode != ACKNOWLEDGE) {				sendreq(ERRORNXIT, "Protocol error\n");				cleanup(10, 1, "Protocol error");			}		}	} else {/* * If not using the extended protocol handle each message type * locally. */		lastsend = opcode;		switch(opcode) {/* * Get login user name. */		case GETNAME:		case GETENAME:			if(!notty) {				getloginname(data);				bcopy(&utmp, req->data, sizeof utmp);				req->length = sizeof utmp;			}			break;/* * Get users password. */		case GETPWD:		case GETEPWD:			if(!notty) {				pp = getpass(data);				strncpy(req->data, pp, REQDATASIZ);				req->length = strlen(pp) + 1;			}			break;/* * Display an error message. */		case ERROR:		case ERRORNXIT:			if(data && length > 0) {				fputs(data, stdout);				fflush(stdout);			}			break;/* * Display a non-error message. */		case VALID:		case VALIDNXIT:		case CHGPWD:			if(data && length > 0) {				fputs(data, stdout);				fflush(stdout);			}			break;/* * Only meaningful to extended protocol. */		case INITIALIZE:			break;		}	}}/* * Function to receive a message from the user, either through prompter * or some other route. */static getreq(req)REQ *req;{	int i;/* * If using extended protocol just retrieve a packet from stdin. */	if(eflag) {		GETREQ(req, i);	} else {/* * If not using extended protocol handle each case locally.  Look at * the last sent message to determine what input should be obtained. */		i = 0;		switch(lastsend) {/* * Waiting for input. */		case GETNAME:		case GETENAME:		case GETPWD:		case GETEPWD:			switch(lastsend) {/* * Waiting for a login name. */			case GETNAME:			case GETENAME:				req->opcode = NAME;				break;/* * Waiting for a password. */			case GETPWD:			case GETEPWD:				req->opcode = PASSWD;				break;			}/* * if notty is true we are talking to an old prompter.  Otherwise * we are talking to a simple tty and all cases are actually handled * in sendreq(). */			if(notty) {				i = fgets(req->data, REQDATASIZ, stdin) != NULL;				if(i)					req->length = strlen(req->data) + 1;				else {					req->length = 0;					i = -1;				}			}			break;/* * The initialize case is only meaningful with the extended protocol. */		case INITIALIZE:			break;		}		lastsend = -1;	}	return i;}/* * Prompter is used to solicit login identity and authentication * through a workstation display. */void start_prompter(prompter, tty) char *prompter;char *tty;{	int infds[2], outfds[2];	int i;		pipe(infds);	dup2(infds[0], 10);	close(infds[0]);	infds[0] = 10;	dup2(infds[1], 11);	close(infds[1]);	infds[1] = 11;	pipe(outfds);	dup2(outfds[0], 12);	close(outfds[0]);	outfds[0] = 12;	dup2(outfds[1], 13);	close(outfds[1]);	outfds[1] = 13;	if(eflag) {		close(2);		i = open("/dev/null", O_WRONLY);		if(i != 2) {			dup2(i, 2);			close(i);		}	}	if(prompt_pid = fork()) {		close(infds[1]);		close(outfds[0]);		/*		 * parents stdin;                 */		dup2(infds[0], 0);		close(infds[0]);		/* stdout */		dup2(outfds[1], 1);		if(!eflag) {			close(2);			dup2(outfds[1], 2);		}		close(outfds[1]);	} else {		close(infds[0]);		close(outfds[1]);		/* child stdin */		dup2(outfds[0], 0);		close(outfds[0]);		/* stdout */		dup2(infds[1], 1);		close(infds[1]);		if(eflag)			execlp(prompter, prompter, "-e", tty, 0);		else			execlp(prompter, prompter, tty, 0);		exit(0);	}	  }/* * audit_event() logs a LOGIN audit event. */audit_event(code, message)int code;char *message;{#ifndef	NOAUDIT	char tmask[AUD_NPARAM];	char *ar[AUD_NPARAM];	int i=0;	static char name[9];	static char host[17];/*  Fill in tokens.*/	strncpy(name, utmp.ut_name, 8);	tmask[i] = T_LOGIN;	ar[i++] = name;	if(pwd) {		tmask[i] = T_HOMEDIR;		ar[i++] = pwd->pw_dir;		tmask[i] = T_SHELL;		ar[i++] = pwd->pw_shell;	}	if(code)		tmask[i] = T_ERROR;	else		tmask[i] = T_RESULT;	ar[i++] = (char *) code;	if(message) {		tmask[i] = T_CHARP;		ar[i++] = message;	}	if(tty) {		tmask[i] = T_DEVNAME;		ar[i++] = tty;	}	strncpy(host, utmp.ut_host, 16);	if(*host) {		tmask[i] = T_CHARP;

⌨️ 快捷键说明

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