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

📄 login.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
		ar[i++] = host;	}	if(i < AUD_NPARAM)		tmask[i] = '\0';	if ( audgen ( LOGIN, tmask, ar ) == -1 ) perror ( "audgen" );#endif	NOAUDIT}/* * Cleanup() is the general error exit routine. */cleanup(time, code, message)int time;int code;char *message;{	int pid;		signal(SIGALRM, exit_handler);	if(code && message) {		audit_event(code, message);	}	alarm(60);	fflush(stdout);	fflush(stderr);	close(1);	close(2);	if(notty) {		for(pid=wait(0);pid != prompt_pid && pid != -1;pid = wait(0));	} else {		ioctl(0, TIOCHPCL, (struct sgttyb *) 0);		sleep(time);	}	close(0);	exit(code);}static int intcount = 0;void no_dir(i, j, k)int i, j, *k;{	intcount++;}/* * The main program. */main(argc, argv)	char *argv[];{	register char *namep;	int pflag = 0;		/* preserve environment from getty */	int t, f, c;	int invalid, quietlog;	int lcmask;	FILE *nlfd;	char *ttyn;	int ldisc = 0, zero = 0;	struct ttyent *t_ent;        char *cmd = NULL;	    char *prompter = NULL;	    static int first = TRUE;	REQ request;	REQ *req = &request;	extern int soft_exp, sec_level;	char theKey, *pKey, *pChar;	ver_t ultrix_v;	struct utsname un;        struct svcinfo *svcp;	int i, j, status, diff;	char lastmessage[100];#ifdef AUTHEN	char namebuf[ANAME_SZ];	char *ptr;#endif AUTHEN#ifndef	NOAUDIT/*  Turn off all auditing except for LOGIN and setgroups.*/	if ( audcntl ( SET_PROC_ACNTL, (char *)0, 0, AUDIT_AND, 0 ) == -1 ) perror ( "audcntl" );  	A_PROCMASK_SET ( buf, SYS_setgroups, 1, 1 );	A_PROCMASK_SET ( buf, LOGIN, 1, 1 );	if ( audcntl ( SET_PROC_AMASK, buf, LEN, 0, 0 ) == -1 ) perror ( "audcntl" );#endif	NOAUDIT	for (t = getdtablesize(); t >= 3; t--)	  close(t);	config_auth();	signal(SIGALRM, timedout);	signal(SIGQUIT, SIG_IGN);	signal(SIGINT, SIG_IGN);	setpriority(PRIO_PROCESS, 0, 0);	quota(Q_SETUID, 0, 0, 0);	/*	 * -r is used by rlogind to cause the autologin protocol;	 * -h is used by other servers to pass the name of the	 *     remote host to login so that it may be placed in utmp and wtmp	 * -p is used by getty to tell login not to destroy the environment	 * -P is used to specify a prompting program.	 * -C is used to specify a command to be execed by the users shell	 *     if the user passes the authentication and auth.	 * -e is used to specify extended prompter communications protocol.	 *     It is only meaningful in the presence of "-P".	 *//*	Initialize Kerberos if possibly needed 	*/#ifdef AUTHEN        if((svcp = getsvc()) == NULL)                {                fputs(" Cannot access security type\n", stderr);                exit(0);                }        if(svcp->svcauth.seclevel >= SEC_UPGRADE)                {                for (i = 0 ; svcp->svcpath[SVC_AUTH][i] != SVC_LAST; i++)                        if (svcp->svcpath[SVC_AUTH][i] == SVC_BIND) {                               if(gethostname(namebuf, sizeof(namebuf)) == -1)                                        {                                        fputs("gethostname failure\n", stderr);                                        }			if((ptr = index(namebuf, '.')) != (char *)0)				*ptr = '\0';                        if(krb_svc_init("hesiod", namebuf, (char *)NULL, 0,                               (char *)NULL, "/var/dss/kerberos/tkt/tkt.login")                                       != RET_OK) {                               fputs("Kerberos initialization failure\n",stderr);                                }			}                }#endif AUTHEN	if (argc > 1) {		if (strcmp(argv[1], "-r") == 0) {			rflag = doremotelogin(argv[2]);			SCPYN(utmp.ut_host, argv[2]);			argc = 0;		}		if (strcmp(argv[1], "-h") == 0 && getuid() == 0) {			dflag = dodecnetlogin();			SCPYN(utmp.ut_host, argv[2]);			argc = 0;		}		if (argc > 1 && strcmp(argv[1], "-p") == 0) {			argv++;			pflag = 1;			argc -= 1;		}		if (argc > 2 && strcmp(argv[1], "-P") == 0) {			if(getuid() == 0) {				notty = TRUE;				prompter = argv[2];			}			argv += 2;			argc -= 2;		}		if (argc > 2 && strcmp(argv[1], "-C") == 0) {			if(getuid() == 0) {				quietlog = TRUE;				cmd = argv[2];			}			argv += 2;			argc -= 2;		}		if (argc > 1 && strcmp(argv[1], "-e") == 0 && getuid() == 0) {			notty = TRUE;			eflag = 1;			argv++;			argc--;		}	}        if( ! notty ) {		ioctl(0, TIOCLGET, &lcmask);		lcmask &= LPASS8;		ioctl(0, TIOCLSET, &zero);		lcmask |= (LPRTERA | LCRTBS | LCRTERA);		ioctl(0, TIOCLSET, &lcmask);		ioctl(0, TIOCNXCL, 0);		ioctl(0, FIONBIO, &zero);		ioctl(0, FIOASYNC, &zero);		ioctl(0, TIOCGETP, &ttyb);		/* If on a LAT terminal, store the LAT server's name		 * into the host field of the utmp record.		 */		if (ioctl(0, LIOCTTYI, &ltattyi) == 0) {		    SCPYN(utmp.ut_host, ltattyi.lta_server_name);		}		/*		 * If talking to an rlogin process,		 * propagate the terminal type and		 * baud rate across the network.		 */		if (rflag)			doremoteterm(term, &ttyb);		ioctl(0, TIOCSLTC, &ltc);		ioctl(0, TIOCSETC, &tc);		ioctl(0, TIOCSETP, &ttyb);		ttyn = ttyname(0);		if (ttyn == (char *)0)			ttyn = "/dev/tty??";		tty = rindex(ttyn, '/');		if (tty == NULL)			tty = ttyn;		else			tty++;	} else {		if(argc > 1)		  tty = argv[1];		argc--;		argv++;	}	if(prompter != NULL) {		start_prompter(prompter, tty);	} else	  alarm(timeout);		openlog("login", 0);	if(eflag) {/* * If extended login protocol get rid of stderr to prevent spurious data * from getting into the prompter conversation.  All errors are reported * through the protocol using sendreq(). */		close(2);/* * Process the initial message from prompter. */		if(getreq(req) < 0)			cleanup(5, 1, "Prompter died");		if(req->opcode == INITIALIZE)			sendreq(INITIALIZE, VERSION);		else {			sendreq(ERRORNXIT, "Protocol error\n");			cleanup(10, 1, "Protocol error");		}	}	t = 0;	do {                if(!notty) {                        ldisc = 0;                        ioctl(0, TIOCSETD, &ldisc);		}		invalid = FALSE;		SCPYN(utmp.ut_name, "");		/*		 * Name specified, take it.		 */		if (argc > 1) {			SCPYN(utmp.ut_name, argv[1]);			argc = 0;		} else if (notty) {/* * Talking to prompter. */			/*			 * 029 - GAG			 * get the string and decypher			 */			sendreq(GETENAME, (char *)0);			if(getreq(req) < 0)				cleanup(5, 1, "Prompter died");			if(req->opcode != NAME) {				sendreq(ERRORNXIT, "Protocol error\n");				cleanup(10, 1, "Protocol error");			}/* * unsalt the string. */			pChar = req->data;			pKey = pChar++;			for (i = req->length; i && (*pChar) && (*pChar != '\n'); i--) {				*pKey ^= *pChar;				pKey = pChar++;			}			theKey = *pKey; /* save the Key */			*pKey = NULL;			if(!eflag) {				if(sscanf(req->data, "name: %s", utmp.ut_name) != 1)					utmp.ut_name[0] = '\0';			} else {				if(req->length > sizeof utmp.ut_name)					req->length = sizeof utmp.ut_name;				bzero(utmp.ut_name, sizeof utmp.ut_name);				bcopy(req->data, utmp.ut_name, req->length);			}			if(first) {				alarm(timeout);				first = FALSE;			}		}				/*		 * If remote login take given name,		 * otherwise prompt user for something.		 */		if (rflag || dflag) {			SCPYN(utmp.ut_name, lusername);			/* autologin failed, prompt for passwd */			if (rflag == -1)				rflag = 0;			if (dflag == -1)				dflag = 0;		} else			getloginname(&utmp);                if (!notty && !strcmp(pwd->pw_shell, "/bin/csh")) {			ldisc = NTTYDISC;			ioctl(0, TIOCSETD, &ldisc);		}		/*		 * If "termio" is specified in /etc/ttys then use the TERMIODISC		 * line discipline.		 */		if ((t_ent = getttynam(tty)) != NULL)			if (t_ent->ty_status & TTY_TERMIO){				ldisc = TERMIODISC;				ioctl(0, TIOCSETD, &ldisc);			}		/*		 * If no remote login authentication and		 * a password exists for this user, prompt		 * for one and verify it.		 */		if(sec_level >= SEC_UPGRADE && (auth == NULL || auth->a_uid != pwd->pw_uid))			auth = getauthuid(pwd->pw_uid);		if(!rflag && !dflag) {			setpriority(PRIO_PROCESS, 0, -4);			if( !notty ) {				if((sec_level < SEC_UPGRADE) ||				    sec_level == SEC_UPGRADE && strcmp(pwd->pw_passwd, "*")) {					if(*pwd->pw_passwd)						pp = getpass("Password:");					else						pp = "";				} else {					if(!auth || *auth->a_password)						pp = getpass("Password:");					else						pp = "";				}			} else {/* * Talking to prompter. */				int tmp = alarm(10);				void (*handler)();				/*				 * 029 - GAG				 * unbuffer stdin, line[0] is the Key,				 * line[1...] is the Cypher,				 */				handler = signal(SIGALRM, exit_handler);				if(!eflag)					setbuf(stdin, (char *) NULL);				sendreq(GETEPWD, (char *)0);				if(getreq(req) < 0)					cleanup(5, 1, "Prompter died");				if(req->opcode != PASSWD) {					sendreq(ERRORNXIT, "Protocol error\n");					cleanup(10, 1, "Protocol error");				}				if(eflag) {					LISTOFPASSWORDS *lop = (LISTOFPASSWORDS *)req->data;					pp = pChar = lop->passwords[0].data;					pKey = pChar++;					i = lop->passwords[0].length-1;				} else {					for(i=req->length+1; i; i--)						req->data[i] = req->data[i-1];					pChar = req->data;					pKey = pChar++;					*pKey = theKey;					i = req->length;				}				alarm(tmp);				signal(SIGALRM, handler);				/*				 * 029 - GAG				 * decypher line,				 * line[0...] becomes plaintext				 */				for (; i && (*pChar != '\n'); i--) {					*pKey ^= *pChar;					pKey = pChar++;				}				*pKey = NULL;					if(!eflag) { 					if(sscanf(req->data,"password: %[^\n]\n", req->data) != 1)						req->data[0] = '\0';					pp = req->data;				}			}			if(sec_level > SEC_UPGRADE || (sec_level == SEC_UPGRADE && !strcmp(pwd->pw_passwd, "*"))) {				if(auth && !(!*auth->a_password && *pp)) {					namep = crypt16(pp, auth->a_password);					pp = auth->a_password;				} else {					pp = "Nologin";					namep = "";				}			} else if(!(!*pwd->pw_passwd && *pp)) {				namep = crypt(pp, pwd->pw_passwd);				pp = pwd->pw_passwd;			} else {				pp = "Nologin";				namep = "";			}			setpriority(PRIO_PROCESS, 0, 0);			if (strcmp(namep, pp)) {				bzero(req->data, REQDATASIZ);				invalid = TRUE;				if(sec_level >= SEC_UPGRADE) {					if(auth=getauthuid(pwd->pw_uid))						if(svc_lastlookup == SVC_LOCAL) {							auth->a_fail_count++;							storeauthent(auth);						}				}			}			bzero(req->data, REQDATASIZ);		}		/*		 * If user not super-user, check for logins disabled.		 */		if (!invalid && pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) {			char error[REQDATASIZ];			int i;			for(i=0; (c=getc(nlfd)) != EOF && i < REQDATASIZ-1; i++)				error[i] = c;			error[i++] = '\0';			sendreq(ERROR, error);                        cleanup(5, 1, "Logins disabled");		}		/*		 * If valid so far and root is logging in,		 * see if root logins on this terminal are permitted.		 */		if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) {			sendreq(ERROR, "Requires secure terminal\n");			syslog(LOG_INFO, "ROOT LOGIN REFUSED %s", tty);			invalid = TRUE;			cleanup(5, 1, "Unsecure terminal");		}		if(!invalid && sec_level >= SEC_UPGRADE) {			if(!(auth->a_authmask&A_LOGIN)) {				sendreq(ERROR, "This account has been disabled\n");				sendreq(ERRORNXIT, (char *)0);				cleanup(5, 1, "Account disabled");			}		}		if(!invalid && sec_level >= SEC_UPGRADE && auth->a_pw_maxexp) {/* * Check for password expiration. */			diff = auth->a_pass_mod				+ auth->a_pw_maxexp - time((long *) 0);			if(diff < 0) {				if(-diff > soft_exp || !(auth->a_authmask&A_CHANGE_PASSWORD)) {					sendreq(ERROR, "Your password has expired\n");					sendreq(ERRORNXIT, (char *)0);					invalid = TRUE;					cleanup(5, 1, "Password expired");				} else {					sendreq(CHGPWD, "Your password has expired, please change it\n");					endauthent();					if((i=vfork()) < 0) {						invalid = TRUE;						sendreq(ERRORNXIT, "Unable to fork\n");						cleanup(5, 1, "Unable to fork");					}					if(i == 0) {						chdir("/"); /* * Fire up passwd(1) to force user to set their password. */						if(eflag) 							execl("/bin/passwd", "/bin/passwd", "-ea", pwd->pw_name, (char *)0);						else {							setuid(pwd->pw_uid);							setgid(pwd->pw_gid);							execl("/bin/passwd", "passwd", pwd->pw_name, (char *) 0);						}						sendreq(ERROR, "Unable to exec passwd\n");						exit(1);					} else {						while((j=wait(&status)) != i && j >= 0) ;						if(status) {							invalid = TRUE;							sendreq(ERRORNXIT, "Failed to set new password\n");							cleanup(5, 1, "Failed to set new password");						} else {							if(svc_lastlookup == SVC_LOCAL) {								if(!(auth=getauthuid(pwd->pw_uid))) {									sendreq(ERRORNXIT, "Failed to retrieve auth record\n");									cleanup(5, 2, "No auth record");								}							} else								auth->a_pass_mod = time((long *) 0);						}					}				}			}		}		if (invalid) {			if (++t >= 5) {				sendreq(ERRORNXIT, "Login incorrect\n");				syslog(LOG_INFO,				    "REPEATED LOGIN FAILURES %s, %s",					tty, utmp.ut_name);                                cleanup(5, 1, "Repeated login failures");			} else {				if(pwd == &nouser)					audit_event(1, "Invalid account");				else					audit_event(1, "Failed authentication");				sendreq(ERROR, "Login incorrect\n");			}		} else {			if(sec_level >= SEC_UPGRADE) {				if(auth->a_fail_count) {					char line[BUFSIZ];					int i;					i = auth->a_fail_count;					auth->a_fail_count = 0;					if(svc_lastlookup == SVC_LOCAL)						storeauthent(auth);					sprintf(line, "There have been %d unsuccessful login attempts on your account\n", i);					sendreq(ERROR, line);					if(!notty)						fputs("", stdout);				}				diff = auth->a_pass_mod					+ auth->a_pw_maxexp - time((long *) 0);				if(auth->a_pw_maxexp && diff < 5*24*60*60) {					char line[BUFSIZ];					if(diff < 24*60*60)						strcpy(line, "Your password will expire very soon\n");					else						sprintf(line, "Your password will expire in %d days\n",							diff/(24*60*60));					sendreq(ERROR, line);				}			}			if(notty && !eflag) {				sendreq(VALIDNXIT, "Login succeeded\n");			}		}		if (*pwd->pw_shell == '\0')			pwd->pw_shell = "/bin/sh";		/*		 * Remote login invalid must have been because		 * of a restriction of some sort, no extra chances.		 */		if ((rflag|dflag) && invalid)			cleanup(0, 1, "Failed remote login");	} while (invalid);/* committed to login turn off timeout */	alarm(timeout);	if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0) {		if (errno == EUSERS) {			sendreq(ERROR, "Too many users logged on already.\nTry again later.\n");			sendreq(ERRORNXIT, (char *) 0);			cleanup(5, 1, "Too many users");		} else if (errno == EPROCLIM) {			sendreq(ERROR, "You have too many processes running.\n");			sendreq(ERRORNXIT, (char *) 0);			cleanup(5, 1, "Too many processes for user");		} else {			sendreq(ERROR, "Error in quota call\n");			sendreq(ERRORNXIT, (char *) 0);			cleanup(5, 2, "Internal error in quota call");		}	}	/* Do the LMF check.         * The Ultrix version numbers are obtained from the kernel         * by uname().   The release date is defined on the command         * line which compiles this program, or by the pre-processor	 * lines below.	 */	uname(&un);	i = sscanf(un.release, "%hd.%hd", &ultrix_v.v_major, &ultrix_v.v_minor);	if (i==0) {		/* Try again in case it looks like `X4.6' */		i = sscanf(un.release, "%*[^0-9]%hd.%hd", &ultrix_v.v_major,			   &ultrix_v.v_minor);	}	if (i<2)		ultrix_v.v_minor = 0;

⌨️ 快捷键说明

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