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

📄 unix_login.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lintstatic  char sccsid[] = "@(#)unix_login.c 1.1 92/07/30 Copyright Sun Micro";#endif# include <rpc/types.h># include <sys/ioctl.h># include <sys/signal.h># include <sys/file.h># include <pwd.h># include <sys/label.h># include <sys/audit.h># include <pwdadj.h># include <errno.h># include <stdio.h># include <utmp.h># include <signal.h># include <rpcsvc/rex.h>/* * unix_login - hairy junk to simulate logins for Unix * * Copyright (c) 1985 Sun Microsystems, Inc. */char Ttys[] = "/etc/ttys";	/* file to get index of utmp */char Utmp[] = "/etc/utmp";	/* the tty slots */char Wtmp[] = "/var/adm/wtmp";	/* the log information */int Master, Slave;		/* sides of the pty */int InputSocket, OutputSocket;	/* Network sockets */int Helper1, Helper2;		/* pids of the helpers */char UserName[256];		/* saves the user name for loging */char HostName[256];		/* saves the host name for loging */char PtyName[16] = "/dev/ttypn";/* name of the tty we allocated */static int TtySlot;		/* slot number in Utmp */extern fd_set svc_fdset;	/* master file descriptor set */extern int child;		/* pid of the executed process */extern int ChildDied;		/* flag */extern int HasHelper;		/* flag */  /*   * The convention used in auditing is:   *  Argument	Value   * --------- --------   *   0	rpc.rexd   *   1	user name   *   2	hostname   *   3	command   *   4	optional error string   */# define AuditCount 5	/* number of audit parameters */static char *audit_argv[AuditCount] = {"rpc.rexd", "", "", "", ""}; /* * Check for user being able to run on this machine. * returns 0 if OK, TRUE if problem, error message in "error" * copies name of shell and home directory if user is valid. */ValidUser(host, uid, error, shell, dir, cmd)    char *host;		/* passed in */    int uid;    char *error;	/* filled in on return */    char *shell;	/* filled in on return */    char *cmd;		/* passed in */{    struct passwd *pw, *getpwuid();    struct passwd_adjunct *apw, *getpwanam();    audit_state_t audit_state;	/* determines auditing flags */        if (issecure()) {        setauid(0);	audit_state.as_success = AU_LOGIN;	audit_state.as_failure = AU_LOGIN;        setaudit(&audit_state);    }    audit_argv[2] = host;    if (cmd != NULL)    	audit_argv[3] = cmd;/*    if (uid == 0) {    	errprintf(error,"rexd: root execution not allowed\n",uid);	audit_argv[1] = "root";	audit_note(1, error);	return(1);    }*/    pw = getpwuid(uid);    if (pw == NULL || pw->pw_name == NULL) {    	errprintf(error,"rexd: User id %d not valid\n",uid);	audit_note(1, error);	return(1);    }    strncpy(UserName, pw->pw_name, sizeof(UserName)-1 );    strncpy(HostName, host, sizeof(HostName)-1 );    strcpy(shell,pw->pw_shell);    strcpy(dir,pw->pw_dir);    setproctitle(pw->pw_name, host);      /*       * User has been validated, now do some auditing work       */    audit_argv[1] = pw->pw_name;    if (cmd == NULL)    	audit_argv[3] = shell;    setauid(pw->pw_uid);    if (issecure() == 0)	return(0);    if ((apw = getpwanam(pw->pw_name)) != NULL) {	audit_state.as_success = 0;	audit_state.as_failure = 0;	if ((getfauditflags(&apw->pwa_au_always, 		 &apw->pwa_au_never, &audit_state)) == 0) {		/*		 * if we can't tell how to audit from the flags, 		 * audit everything that's not never for this user.		 */		audit_state.as_success = apw->pwa_au_never.as_success ^ (-1);		audit_state.as_failure = apw->pwa_au_never.as_success ^ (-1);        }    } else {	audit_state.as_success = -1;	audit_state.as_failure = -1;    }    setaudit(&audit_state);    return(0);}/* * Add an audit record with argv that was pre-set, plus the given string */audit_note(retcode, s)	int retcode;	char *s;{	audit_argv[4] = s;	audit_text(AU_LOGIN, retcode, retcode, AuditCount, audit_argv);}/* *  eliminate any controlling terminal that we have already */NoControl(){    int devtty;    devtty = open("/dev/tty",O_RDWR);    if (devtty > 0) {    	    ioctl(devtty, TIOCNOTTY, NULL);	    close(devtty);    }}/* * Allocate a pseudo-terminal * sets the global variables Master and Slave. * returns 1 on error, 0 if OK */AllocatePtyMaster(socket0, socket1)    int socket0, socket1;{# define Sequence "0123456789abcdef"# define MajorPos 8	/* /dev/ptyXx */# define MinorPos 9	/* /dev/ptyxX */# define SidePos 5	/* /dev/Ptyxx */    static char ptySequence[] = Sequence;    char maj, min;    int pgrp;    int on = 1;    signal(SIGHUP,SIG_IGN);    signal(SIGTTOU,SIG_IGN);    signal(SIGTTIN,SIG_IGN);    for (maj = 'p'; maj <= 's'; maj++)      for (min = 0; min < strlen(Sequence); min++ ) {	    PtyName[MajorPos] = maj;	    PtyName[MinorPos] = ptySequence[min];	    PtyName[SidePos] = 'p';	    Master = open(PtyName, O_RDWR);	    if (Master < 0) {		continue;	    }	    NoControl();	    LoginUser();	    pgrp = getpid();	    setpgrp(pgrp, pgrp);	    InputSocket = socket0;	    OutputSocket = socket1;	    ioctl(Master, FIONBIO, &on);	    FD_SET(InputSocket, &svc_fdset);	    FD_SET(Master, &svc_fdset);	    return(0);	}    /*     * No pty found!     */    return(1);}AllocatePtySlave(){  PtyName[SidePos] = 't';  Slave = open (PtyName, O_RDWR);  if (Slave < 0) {    perror (PtyName);    exit (1);  }}  /*   * Special processing for interactive operation.   * Given pointers to three standard file descriptors,   * which get set to point to the pty.   */DoHelper(pfd0, pfd1, pfd2)    int *pfd0, *pfd1, *pfd2;{    int pgrp;    pgrp = getpid();    setpgrp(pgrp, pgrp);    ioctl(Slave, TIOCSPGRP, &pgrp);    signal( SIGINT, SIG_IGN);    close(Master);    close(InputSocket);    close(OutputSocket);    *pfd0 = Slave;    *pfd1 = Slave;    *pfd2 = Slave;}/* * destroy the helpers when the executing process dies */KillHelper(grp)    int grp;{    close(Master);    FD_CLR(Master, &svc_fdset);    close(InputSocket);    FD_CLR(InputSocket, &svc_fdset);    close(OutputSocket);    LogoutUser();    if (grp) killpg(grp,SIGKILL);}/* * edit the Unix traditional data files that tell who is logged * into "the system" */LoginUser(){  FILE *ttysFile;  register char *last = PtyName + sizeof("/dev");  char line[256];  int count;  int utf;  struct utmp utmp;    ttysFile = fopen(Ttys,"r");  TtySlot = 0;  count = 0;  if (ttysFile != NULL) {      while (fgets(line, sizeof(line), ttysFile) != NULL) {        register char *lp;	lp = line + strlen(line) - 1;	if (*lp == '\n') *lp = '\0';	count++;	if (strcmp(last,line+2)==0) {	  TtySlot = count;	  break;	}      }      fclose(ttysFile);  }  if (TtySlot > 0 && (utf = open(Utmp,O_WRONLY)) >= 0) {      lseek(utf, TtySlot*sizeof(utmp), L_SET);      strncpy(utmp.ut_line,last,sizeof(utmp.ut_line));      strncpy(utmp.ut_name,UserName,sizeof(utmp.ut_name));      strncpy(utmp.ut_host,HostName,sizeof(utmp.ut_host));      time(&utmp.ut_time);      write(utf, (char *)&utmp, sizeof(utmp));      close(utf);  }  if (TtySlot > 0 && (utf = open(Wtmp,O_WRONLY)) >= 0) {      lseek(utf, (long)0, L_XTND);      write(utf, (char *)&utmp, sizeof(utmp));      close(utf);  }}/* * edit the Unix traditional data files that tell who is logged * into "the system". */LogoutUser(){  int utf;  register char *last = PtyName + sizeof("/dev");  struct utmp utmp;  if (TtySlot > 0 && (utf = open(Utmp,O_RDWR)) >= 0) {      lseek(utf, TtySlot*sizeof(utmp), L_SET);      read(utf, (char *)&utmp, sizeof(utmp));      if (strncmp(last,utmp.ut_line,sizeof(utmp.ut_line))==0) {	lseek(utf, TtySlot*sizeof(utmp), L_SET);	strcpy(utmp.ut_name,"");	strcpy(utmp.ut_host,"");	time(&utmp.ut_time);	write(utf, (char *)&utmp, sizeof(utmp));      }      close(utf);  }  if (TtySlot > 0 && (utf = open(Wtmp,O_WRONLY)) >= 0) {      lseek(utf, (long)0, L_XTND);      strncpy(utmp.ut_line,last,sizeof(utmp.ut_line));      write(utf, (char *)&utmp, sizeof(utmp));      close(utf);  }  TtySlot = 0;}/* * set the pty modes to the given values */SetPtyMode(mode)    struct rex_ttymode *mode;{    int ldisc = NTTYDISC;        PtyName[SidePos] = 't';    Slave = open (PtyName, O_RDWR);    if (Slave < 0) {      perror (PtyName);      exit (1);    }    ioctl(Slave, TIOCSETD, &ldisc);    ioctl(Slave, TIOCSETN, &mode->basic);    ioctl(Slave, TIOCSETC, &mode->more);    ioctl(Slave, TIOCSLTC, &mode->yetmore);    ioctl(Slave, TIOCLSET, &mode->andmore);    close (Slave);}/* * set the pty window size to the given value */SetPtySize(size)    struct ttysize *size;{    int pgrp;    PtyName[SidePos] = 't';    Slave = open (PtyName, O_RDWR);    if (Slave < 0) {      perror (PtyName);      exit (1);    }    (void) ioctl(Slave, TIOCSSIZE, size);    SendSignal(SIGWINCH);    close (Slave);}/* * send the given signal to the group controlling the terminal */SendSignal(sig)    int sig;{    int pgrp;    if (ioctl(Slave, TIOCGPGRP, &pgrp) >= 0)    	(void) killpg( pgrp, sig);}/* * called when the main select loop detects that we might want to * read something. */HelperRead(fdp)	fd_set *fdp;{    char buf[128];    int cc;    extern int errno;    int mask;    mask = sigsetmask (sigmask (SIGCHLD));    if (FD_ISSET(Master, fdp)) {	FD_CLR(Master, fdp);    	cc = read(Master, buf, sizeof buf);	if (cc > 0)		(void) write(OutputSocket, buf, cc);	else {	  	shutdown(OutputSocket, 1);		FD_CLR(Master, &svc_fdset);		if (cc < 0 && errno != EINTR && errno != EWOULDBLOCK &&		    errno != EIO)			perror("pty read");		if (ChildDied) {		  KillHelper (child);		  HasHelper = 0;		  if (FD_ISSET(InputSocket, fdp))		    FD_CLR(InputSocket, fdp);		  goto done;		}	}    }    if (FD_ISSET(InputSocket, fdp)) {	FD_CLR(InputSocket, fdp);    	cc = read(InputSocket, buf, sizeof buf);	if (cc > 0)		(void) write(Master, buf, cc);	else {		if (cc < 0 && errno != EINTR && errno != EWOULDBLOCK)			perror("socket read");		FD_CLR(InputSocket, &svc_fdset);	}    }  done:    sigsetmask (mask);}

⌨️ 快捷键说明

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