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

📄 login.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 3 页
字号:
	    int wtmp;	    if((wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {		write(wtmp, (char *)&ut, sizeof(ut));		close(wtmp);	    }	}#else	/* Probably all this locking below is just nonsense,	   and the short version is OK as well. */	{ 	    int lf, wtmp;	    if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {		flock(lf, LOCK_EX);		if ((wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {		    write(wtmp, (char *)&ut, sizeof(ut));		    close(wtmp);		}		flock(lf, LOCK_UN);		close(lf);	    }	}#endif#endif    }        dolastlog(quietlog);        chown(ttyn, pwd->pw_uid,	  (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);    chmod(ttyn, TTY_MODE);#ifdef CHOWNVCS    /* if tty is one of the VC's then change owner and mode of the        special /dev/vcs devices as well */    if (consoletty(0)) {	chown(vcsn, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid));	chown(vcsan, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid));	chmod(vcsn, TTY_MODE);	chmod(vcsan, TTY_MODE);    }#endif    setgid(pwd->pw_gid);    #ifdef HAVE_QUOTA    quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);#endif        if (*pwd->pw_shell == '\0')      pwd->pw_shell = _PATH_BSHELL;        /* preserve TERM even without -p flag */    {	char *ep;		if(!((ep = getenv("TERM")) && (termenv = strdup(ep))))	  termenv = "dumb";    }        /* destroy environment unless user has requested preservation */    if (!pflag)      {          environ = (char**)malloc(sizeof(char*));	  memset(environ, 0, sizeof(char*));      }        setenv("HOME", pwd->pw_dir, 0);      /* legal to override */    if(pwd->pw_uid)      setenv("PATH", _PATH_DEFPATH, 1);    else      setenv("PATH", _PATH_DEFPATH_ROOT, 1);        setenv("SHELL", pwd->pw_shell, 1);    setenv("TERM", termenv, 1);        /* mailx will give a funny error msg if you forget this one */    {      char tmp[MAXPATHLEN];      /* avoid snprintf */      if (sizeof(_PATH_MAILDIR) + strlen(pwd->pw_name) + 1 < MAXPATHLEN) {	      sprintf(tmp, "%s/%s", _PATH_MAILDIR, pwd->pw_name);	      setenv("MAIL",tmp,0);      }    }        /* LOGNAME is not documented in login(1) but       HP-UX 6.5 does it. We'll not allow modifying it.       */    setenv("LOGNAME", pwd->pw_name, 1);#ifdef USE_PAM    {	int i;	char ** env = pam_getenvlist(pamh);	if (env != NULL) {	    for (i=0; env[i]; i++) {		putenv(env[i]);		/* D(("env[%d] = %s", i,env[i])); */	    }	}    }#endif#ifdef DO_PS_FIDDLING    setproctitle("login", username);#endif        if (!strncmp(tty_name, "ttyS", 4))      syslog(LOG_INFO, _("DIALUP AT %s BY %s"), tty_name, pwd->pw_name);        /* allow tracking of good logins.       -steve philp (sphilp@mail.alliance.net) */        if (pwd->pw_uid == 0) {	if (hostname)	  syslog(LOG_NOTICE, _("ROOT LOGIN ON %s FROM %s"),		 tty_name, hostname);	else	  syslog(LOG_NOTICE, _("ROOT LOGIN ON %s"), tty_name);    } else {	if (hostname) 	  syslog(LOG_INFO, _("LOGIN ON %s BY %s FROM %s"), tty_name, 		 pwd->pw_name, hostname);	else 	  syslog(LOG_INFO, _("LOGIN ON %s BY %s"), tty_name, 		 pwd->pw_name);    }        if (!quietlog) {	motd();#ifdef DO_STAT_MAIL	/*	 * This turns out to be a bad idea: when the mail spool	 * is NFS mounted, and the NFS connection hangs, the	 * login hangs, even root cannot login.	 * Checking for mail should be done from the shell.	 */	{	    struct stat st;	    char *mail;		    mail = getenv("MAIL");	    if (mail && stat(mail, &st) == 0 && st.st_size != 0) {		if (st.st_mtime > st.st_atime)			printf(_("You have new mail.\n"));		else			printf(_("You have mail.\n"));	    }	}#endif    }        signal(SIGALRM, SIG_DFL);    signal(SIGQUIT, SIG_DFL);    signal(SIGTSTP, SIG_IGN);#ifdef USE_PAM    /*     * We must fork before setuid() because we need to call     * pam_close_session() as root.     */        childPid = fork();    if (childPid < 0) {       int errsv = errno;       /* error in fork() */       fprintf(stderr, _("login: failure forking: %s"), strerror(errsv));       PAM_END;       exit(0);    }    if (childPid) {       /* parent - wait for child to finish, then cleanup session */       signal(SIGHUP, SIG_IGN);       signal(SIGINT, SIG_IGN);       signal(SIGQUIT, SIG_IGN);       signal(SIGTSTP, SIG_IGN);       signal(SIGTTIN, SIG_IGN);       signal(SIGTTOU, SIG_IGN);       wait(NULL);       PAM_END;       exit(0);    }    /* child */    /*     * Problem: if the user's shell is a shell like ash that doesnt do     * setsid() or setpgrp(), then a ctrl-\, sending SIGQUIT to every     * process in the pgrp, will kill us.     */    /* start new session */    setsid();    /* make sure we have a controlling tty */    opentty(ttyn);    openlog("login", LOG_ODELAY, LOG_AUTHPRIV);	/* reopen */    /*     * TIOCSCTTY: steal tty from other process group.     */    if (ioctl(0, TIOCSCTTY, 1))	    syslog(LOG_ERR, _("TIOCSCTTY failed: %m"));#endif    signal(SIGINT, SIG_DFL);        /* discard permissions last so can't get killed and drop core */    if(setuid(pwd->pw_uid) < 0 && pwd->pw_uid) {	syslog(LOG_ALERT, _("setuid() failed"));	exit(1);    }        /* wait until here to change directory! */    if (chdir(pwd->pw_dir) < 0) {	printf(_("No directory %s!\n"), pwd->pw_dir);	if (chdir("/"))	  exit(0);	pwd->pw_dir = "/";	printf(_("Logging in with home = \"/\".\n"));    }        /* if the shell field has a space: treat it like a shell script */    if (strchr(pwd->pw_shell, ' ')) {	buff = malloc(strlen(pwd->pw_shell) + 6);	if (!buff) {	    fprintf(stderr, _("login: no memory for shell script.\n"));	    exit(0);	}	strcpy(buff, "exec ");	strcat(buff, pwd->pw_shell);	childArgv[childArgc++] = "/bin/sh";	childArgv[childArgc++] = "-sh";	childArgv[childArgc++] = "-c";	childArgv[childArgc++] = buff;    } else {	tbuf[0] = '-';	xstrncpy(tbuf + 1, ((p = rindex(pwd->pw_shell, '/')) ?			   p + 1 : pwd->pw_shell),		sizeof(tbuf)-1);		childArgv[childArgc++] = pwd->pw_shell;	childArgv[childArgc++] = tbuf;    }    childArgv[childArgc++] = NULL;    execvp(childArgv[0], childArgv + 1);    errsv = errno;    if (!strcmp(childArgv[0], "/bin/sh"))	fprintf(stderr, _("login: couldn't exec shell script: %s.\n"),		strerror(errsv));    else	fprintf(stderr, _("login: no shell: %s.\n"), strerror(errsv));    exit(0);}#ifndef USE_PAMstatic voidgetloginname(void) {    int ch, cnt, cnt2;    char *p;    static char nbuf[UT_NAMESIZE + 1];        cnt2 = 0;    for (;;) {	cnt = 0;	printf(_("\n%s login: "), thishost); fflush(stdout);	for (p = nbuf; (ch = getchar()) != '\n'; ) {	    if (ch == EOF) {		badlogin("EOF");		exit(0);	    }	    if (p < nbuf + UT_NAMESIZE)	      *p++ = ch;	    	    cnt++;	    if (cnt > UT_NAMESIZE + 20) {		fprintf(stderr, _("login name much too long.\n"));		badlogin(_("NAME too long"));		exit(0);	    }	}	if (p > nbuf) {	  if (nbuf[0] == '-')	    fprintf(stderr,		    _("login names may not start with '-'.\n"));	  else {	      *p = '\0';	      username = nbuf;	      break;	  }	}		cnt2++;	if (cnt2 > 50) {	    fprintf(stderr, _("too many bare linefeeds.\n"));	    badlogin(_("EXCESSIVE linefeeds"));	    exit(0);	}    }}#endif/* * Robert Ambrose writes: * A couple of my users have a problem with login processes hanging around * soaking up pts's.  What they seem to hung up on is trying to write out the * message 'Login timed out after %d seconds' when the connection has already * been dropped. * What I did was add a second timeout while trying to write the message so * the process just exits if the second timeout expires. */static voidtimedout2(int sig) {	struct termio ti;    	/* reset echo */	ioctl(0, TCGETA, &ti);	ti.c_lflag |= ECHO;	ioctl(0, TCSETA, &ti);	exit(0);			/* %% */}static voidtimedout(int sig) {	signal(SIGALRM, timedout2);	alarm(10);	fprintf(stderr, _("Login timed out after %d seconds\n"), timeout);	signal(SIGALRM, SIG_IGN);	alarm(0);	timedout2(0);}#ifndef USE_PAMintrootterm(char * ttyn){     int fd;    char buf[100],*p;    int cnt, more = 0;        fd = open(SECURETTY, O_RDONLY);    if(fd < 0) return 1;        /* read each line in /etc/securetty, if a line matches our ttyline       then root is allowed to login on this tty, and we should return       true. */    for(;;) {	p = buf; cnt = 100;	while(--cnt >= 0 && (more = read(fd, p, 1)) == 1 && *p != '\n') p++;	if(more && *p == '\n') {	    *p = '\0';	    if(!strcmp(buf, ttyn)) {		close(fd);		return 1;	    } else	      continue;  	} else {	    close(fd);	    return 0;  	}    }}#endif /* !USE_PAM */jmp_buf motdinterrupt;voidmotd(void) {    int fd, nchars;    void (*oldint)(int);    char tbuf[8192];        if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0)      return;    oldint = signal(SIGINT, sigint);    if (setjmp(motdinterrupt) == 0)      while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)	write(fileno(stdout), tbuf, nchars);    signal(SIGINT, oldint);    close(fd);}voidsigint(int sig) {    longjmp(motdinterrupt, 1);}#ifndef USE_PAM				/* PAM takes care of this */voidchecknologin(void) {    int fd, nchars;    char tbuf[8192];        if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {	while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)	  write(fileno(stdout), tbuf, nchars);	close(fd);	sleepexit(0);    }}#endifvoiddolastlog(int quiet) {    struct lastlog ll;    int fd;        if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {	lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);	if (!quiet) {	    if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&		ll.ll_time != 0) {		    time_t ll_time = (time_t) ll.ll_time;		    printf(_("Last login: %.*s "),			   24-5, ctime(&ll_time));				    if (*ll.ll_host != '\0')			    printf(_("from %.*s\n"),				   (int)sizeof(ll.ll_host), ll.ll_host);		    else			    printf(_("on %.*s\n"),				   (int)sizeof(ll.ll_line), ll.ll_line);	    }	    lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);	}	memset((char *)&ll, 0, sizeof(ll));	time(&ll.ll_time);	xstrncpy(ll.ll_line, tty_name, sizeof(ll.ll_line));	if (hostname)	    xstrncpy(ll.ll_host, hostname, sizeof(ll.ll_host));	write(fd, (char *)&ll, sizeof(ll));	close(fd);    }}voidbadlogin(const char *name) {    if (failures == 1) {	if (hostname)	  syslog(LOG_NOTICE, _("LOGIN FAILURE FROM %s, %s"),		 hostname, name);	else	  syslog(LOG_NOTICE, _("LOGIN FAILURE ON %s, %s"),		 tty_name, name);    } else {	if (hostname)	  syslog(LOG_NOTICE, _("%d LOGIN FAILURES FROM %s, %s"),		 failures, hostname, name);	else	  syslog(LOG_NOTICE, _("%d LOGIN FAILURES ON %s, %s"),		 failures, tty_name, name);    }}/* Should not be called from PAM code... */voidsleepexit(int eval) {    sleep(SLEEP_EXIT_TIMEOUT);    exit(eval);}

⌨️ 快捷键说明

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