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

📄 login.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* This program is derived from 4.3 BSD software and is   subject to the copyright notice below.      The port to HP-UX has been motivated by the incapability   of 'rlogin'/'rlogind' as per HP-UX 6.5 (and 7.0) to transfer window sizes.      Changes:      - General HP-UX portation. Use of facilities not available     in HP-UX (e.g. setpriority) has been eliminated.     Utmp/wtmp handling has been ported.      - The program uses BSD command line options to be used     in connection with e.g. 'rlogind' i.e. 'new login'.      - HP features left out:	    password expiry				    '*' as login shell, add it if you need it   - BSD features left out:         quota checks   	                            password expiry				    analysis of terminal type (tset feature)      - BSD features thrown in:        Security logging to syslogd.                                    This requires you to have a (ported) syslog				    system -- 7.0 comes with syslog   				    'Lastlog' feature.      - A lot of nitty gritty details have been adjusted in favour of     HP-UX, e.g. /etc/securetty, default paths and the environment     variables assigned by 'login'.      - We do *nothing* to setup/alter tty state, under HP-UX this is     to be done by getty/rlogind/telnetd/some one else.      Michael Glad (glad@daimi.dk)   Computer Science Department   Aarhus University   Denmark      1990-07-04      1991-09-24 glad@daimi.aau.dk: HP-UX 8.0 port:   - now explictly sets non-blocking mode on descriptors   - strcasecmp is now part of HP-UX   1992-02-05 poe@daimi.aau.dk: Ported the stuff to Linux 0.12   From 1992 till now (1997) this code for Linux has been maintained at   ftp.daimi.aau.dk:/pub/linux/poe/   1999-02-22 Arkadiusz Mi秌iewicz <misiek@pld.ORG.PL>    - added Native Language Support   Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>    - fixed strerr(errno) in gettext calls *//* * Copyright (c) 1980, 1987, 1988 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley.  The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. *//* * login [ name ] * login -h hostname	(for telnetd, etc.) * login -f name	(for pre-authenticated login: datakit, xterm, etc.) *//* #define TESTING */#ifdef TESTING#include "param.h"#else#include <sys/param.h>#endif#include <stdio.h>#include <ctype.h>#include <unistd.h>#include <getopt.h>#include <memory.h>#include <time.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/file.h>#include <termios.h>#include <string.h>#define index strchr#define rindex strrchr#include <sys/ioctl.h>#include <sys/wait.h>#include <signal.h>#include <errno.h>#include <grp.h>#include <pwd.h>#include <utmp.h>#include <setjmp.h>#include <stdlib.h>#include <string.h>#include <sys/syslog.h>#include <sys/sysmacros.h>#include <netdb.h>#include "pathnames.h"#include "my_crypt.h"#include "login.h"#include "xstrncpy.h"#include "nls.h"#ifdef __linux__#  include <sys/sysmacros.h>#  include <linux/major.h>#endif#ifdef TESTING#  include "utmp.h"#else#  include <utmp.h>#endif#ifdef SHADOW_PWD#  include <shadow.h>#endif#ifdef USE_PAM#  include <security/pam_appl.h>#  include <security/pam_misc.h>#  define PAM_MAX_LOGIN_TRIES	3#  define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \       fprintf(stderr,"\n%s\n",pam_strerror(pamh, retcode)); \       syslog(LOG_ERR,"%s",pam_strerror(pamh, retcode)); \       pam_end(pamh, retcode); exit(1); \   }#  define PAM_END { \	pam_setcred(pamh, PAM_DELETE_CRED); \	retcode = pam_close_session(pamh,0); \	pam_end(pamh,retcode); \}#endif#ifndef __linux__#  include <tzfile.h>#endif#include <lastlog.h>#define SLEEP_EXIT_TIMEOUT 5#ifdef __linux__#define DO_PS_FIDDLING#endif#ifdef DO_PS_FIDDLING#include "setproctitle.h"#endif#if 0/* from before we had a lastlog.h file in linux */struct  lastlog{ long ll_time;  char ll_line[12];  char ll_host[16];};#endif#ifndef USE_PAMstatic void getloginname (void);static void checknologin (void);static int rootterm (char *ttyn);#endifstatic void timedout (int);static void sigint (int);static void motd (void);static void dolastlog (int quiet);#ifdef CRYPTOCARD#include "cryptocard.h"#endif#ifdef	KERBEROS#include <kerberos/krb.h>#include <sys/termios.h>char	realm[REALM_SZ];int	kerror = KSUCCESS, notickets = 1;#endif#ifdef USE_TTY_GROUP#  define TTY_MODE 0620#else#  define TTY_MODE 0600#endif#define	TTYGRPNAME	"tty"		/* name of group to own ttys */#ifndef MAXPATHLEN#  define MAXPATHLEN 1024#endif/* * This bounds the time given to login.  Not a define so it can * be patched on machines where it's too small. */#ifndef __linux__int	timeout = 300;#elseint     timeout = 60;		/* used in cryptocard.c */#endifstruct	passwd *pwd;		/* used in cryptocard.c */#if USE_PAMstatic struct passwd pwdcopy;#endifchar    hostaddress[4];		/* used in checktty.c */char	*hostname;		/* idem */static char	*username, *tty_name, *tty_number;static char	thishost[100];static int	failures = 1;static pid_t	pid;#ifndef __linux__struct	sgttyb sgttyb;struct	tchars tc = {	CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK};struct	ltchars ltc = {	CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT};#endif/* Nice and simple code provided by Linus Torvalds 16-Feb-93 *//* Nonblocking stuff by Maciej W. Rozycki, macro@ds2.pg.gda.pl, 1999.   He writes: "Login performs open() on a tty in a blocking mode.   In some cases it may make login wait in open() for carrier infinitely,   for example if the line is a simplistic case of a three-wire serial   connection. I believe login should open the line in the non-blocking mode   leaving the decision to make a connection to getty (where it actually   belongs). */static voidopentty(const char * tty) {	int i, fd, flags;	fd = open(tty, O_RDWR | O_NONBLOCK);	if (fd == -1) {		syslog(LOG_ERR, _("FATAL: can't reopen tty: %s"),		       strerror(errno));		sleep(1);		exit(1);	}	flags = fcntl(fd, F_GETFL);	flags &= ~O_NONBLOCK;	fcntl(fd, F_SETFL, flags);    	for (i = 0; i < fd; i++)		close(i);	for (i = 0; i < 3; i++)		if (fd != i)			dup2(fd, i);	if (fd >= 3)		close(fd);}/* In case login is suid it was possible to use a hardlink as stdin   and exploit races for a local root exploit. (Wojciech Purczynski). *//* More precisely, the problem is  ttyn := ttyname(0); ...; chown(ttyn);   here ttyname() might return "/tmp/x", a hardlink to a pseudotty. *//* All of this is a problem only when login is suid, which it isnt. */static voidcheck_ttyname(char *ttyn) {	struct stat statbuf;	if (lstat(ttyn, &statbuf)	    || !S_ISCHR(statbuf.st_mode)	    || (statbuf.st_nlink > 1 && strncmp(ttyn, "/dev/", 5))) {		syslog(LOG_ERR, _("FATAL: bad tty"));		sleep(1);		exit(1);	}}/* true if the filedescriptor fd is a console tty, very Linux specific */static intconsoletty(int fd) {#ifdef __linux__    struct stat stb;    if ((fstat(fd, &stb) >= 0) 	&& (major(stb.st_rdev) == TTY_MAJOR)	&& (minor(stb.st_rdev) < 64)) {	return 1;    }#endif    return 0;}#if USE_PAM/* * Log failed login attempts in _PATH_BTMP if that exists. * Must be called only with username the name of an actual user. * The most common login failure is to give password instead of username. */#define	_PATH_BTMP	"/var/log/btmp"static voidlogbtmp(const char *line, const char *username, const char *hostname) {	struct utmp ut;	memset(&ut, 0, sizeof(ut));	strncpy(ut.ut_user, username ? username : "(unknown)",		sizeof(ut.ut_user));	strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));	xstrncpy(ut.ut_line, line, sizeof(ut.ut_line));#if defined(_HAVE_UT_TV)	    /* in <utmpbits.h> included by <utmp.h> */	gettimeofday(&ut.ut_tv, NULL);#else	{		time_t t;		time(&t);		ut.ut_time = t;	    /* ut_time is not always a time_t */	}#endif	ut.ut_type = LOGIN_PROCESS; /* XXX doesn't matter */	ut.ut_pid = pid;	if (hostname) {		xstrncpy(ut.ut_host, hostname, sizeof(ut.ut_host));		if (hostaddress[0])			memcpy(&ut.ut_addr, hostaddress, sizeof(ut.ut_addr));	}#ifdef HAVE_updwtmp		/* bad luck for ancient systems */	updwtmp(_PATH_BTMP, &ut);#endif}#endif	/* USE_PAM */intmain(int argc, char **argv){    extern int optind;    extern char *optarg, **environ;    struct group *gr;    register int ch;    register char *p;    int ask, fflag, hflag, pflag, cnt, errsv;    int quietlog, passwd_req;    char *domain, *ttyn;    char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];    char *termenv;    char *childArgv[10];    char *buff;    int childArgc = 0;#ifdef USE_PAM    int retcode;    pam_handle_t *pamh = NULL;    struct pam_conv conv = { misc_conv, NULL };    pid_t childPid;#else    char *salt, *pp;#endif#ifdef CHOWNVCS    char vcsn[20], vcsan[20];#endif    pid = getpid();    signal(SIGALRM, timedout);    alarm((unsigned int)timeout);    signal(SIGQUIT, SIG_IGN);    signal(SIGINT, SIG_IGN);    setlocale(LC_ALL, "");    bindtextdomain(PACKAGE, LOCALEDIR);    textdomain(PACKAGE);        setpriority(PRIO_PROCESS, 0, 0);#ifdef HAVE_QUOTA    quota(Q_SETUID, 0, 0, 0);#endif#ifdef DO_PS_FIDDLING    initproctitle(argc, argv);#endif        /*     * -p is used by getty to tell login not to destroy the environment     * -f is used to skip a second login authentication      * -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     */    gethostname(tbuf, sizeof(tbuf));    xstrncpy(thishost, tbuf, sizeof(thishost));    domain = index(tbuf, '.');        username = tty_name = hostname = NULL;    fflag = hflag = pflag = 0;    passwd_req = 1;    while ((ch = getopt(argc, argv, "fh:p")) != -1)      switch (ch) {	case 'f':	  fflag = 1;	  break;	  	case 'h':	  if (getuid()) {	      fprintf(stderr,		      _("login: -h for super-user only.\n"));	      exit(1);	  }	  hflag = 1;	  if (domain && (p = index(optarg, '.')) &&	      strcasecmp(p, domain) == 0)	    *p = 0;	  hostname = strdup(optarg); 	/* strdup: Ambrose C. Li */	  {		  struct hostent *he = gethostbyname(hostname);		  /* he points to static storage; copy the part we use */		  hostaddress[0] = 0;		  if (he && he->h_addr_list && he->h_addr_list[0])			  memcpy(hostaddress, he->h_addr_list[0],				 sizeof(hostaddress));	  }	  break;	  	case 'p':	  pflag = 1;	  break;	case '?':	default:	  fprintf(stderr,		  _("usage: login [-fp] [username]\n"));	  exit(1);      }    argc -= optind;    argv += optind;    if (*argv) {	char *p = *argv;	username = strdup(p);	ask = 0;	/* wipe name - some people mistype their password here */	/* (of course we are too late, but perhaps this helps a little ..) */	while(*p)	    *p++ = ' ';    } else        ask = 1;    for (cnt = getdtablesize(); cnt > 2; cnt--)      close(cnt);        ttyn = ttyname(0);    if (ttyn == NULL || *ttyn == '\0') {	/* no snprintf required - see definition of tname */	sprintf(tname, "%s??", _PATH_TTY);	ttyn = tname;    }    check_ttyname(ttyn);    if (strncmp(ttyn, "/dev/", 5) == 0)	tty_name = ttyn+5;    else

⌨️ 快捷键说明

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