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

📄 rlogind.c

📁 压缩包中包含LINUX下多个命令的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  syslog (LOG_INFO, "Connect from %s:%d",           inet_ntoa(auth_data.from.sin_addr), ntohs(auth_data.from.sin_port));  true = 1;  if (keepalive      && setsockopt (infd, SOL_SOCKET, SO_KEEPALIVE, &true, sizeof true) < 0)    syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");#if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_LOWDELAY)  true = IPTOS_LOWDELAY;  if (setsockopt (infd, IPPROTO_IP, IP_TOS, (char *) &true, sizeof true) < 0)    syslog (LOG_WARNING, "setsockopt (IP_TOS): %m");#endif  alarm (60); /* Wait at most 60 seconds. FIXME: configurable? */  /* Read the null byte */  if (read (infd, &c, 1) != 1 || c != 0)    {      syslog (LOG_CRIT, "protocol error: expected 0 byte");      exit (1);    }  alarm (0);  authenticated = rlogind_auth (infd, &auth_data);  pid = forkpty (&master, line, NULL, &win);  if (pid < 0)    {      if (errno == ENOENT)	{	  syslog (LOG_ERR, "Out of ptys");	  fatal (infd, "Out of ptys", 0);	}      else	{	  syslog (LOG_ERR, "forkpty: %m");	  fatal (infd, "Forkpty", 1);	}    }  if (pid == 0)    {      /* Child */      if (infd > 2)	close (infd);      setup_tty (0, &auth_data);      setup_utmp (line);      exec_login (authenticated, &auth_data);      fatal (infd, "can't execute login", 1);    }  /* Parent */  true = 1;  IF_NOT_ENCRYPT (ioctl (infd, FIONBIO, &true));  ioctl (master, FIONBIO, &true);  ioctl (master, TIOCPKT, &true);  netf = infd; /* Needed for cleanup() */  signal (SIGCHLD, cleanup);  protocol (infd, master);  signal (SIGCHLD, SIG_IGN);  cleanup (0);  return 0;}intdo_rlogin(int infd, struct auth_data *ap){  struct passwd *pwd;  int rc;  getstr (infd, &ap->rusername, NULL);  getstr (infd, &ap->lusername, NULL);  getstr (infd, &ap->term, "TERM=");  pwd = getpwnam (ap->lusername);  if (pwd == NULL)    {      syslog(LOG_ERR, "no passwd entry for %s", ap->lusername);      fatal(infd, "Permission denied", 0);    }  if (!allow_root && pwd->pw_uid == 0)    {      syslog(LOG_ERR, "root logins not permitted");      fatal(infd, "Permission denied", 0);    }  rc = iruserok (ap->from.sin_addr.s_addr, 0,		 ap->rusername, ap->lusername);  if (rc)    syslog(LOG_ERR, "iruserok failed: rusername=%s, lusername=%s",	   ap->rusername, ap->lusername);  return rc;}#ifdef KERBEROSintdo_krb_login (int infd, struct auth_data *ap, const char **err_msg){  int rc;  err_msg = NULL;#ifdef KERBEROS_V  if (kerberos == AUTH_KERBEROS_5)    rc = do_krb5_login (infd, ap, err_msg);  else#endif    rc = do_krb4_login (infd, ap, err_msg);    if (rc && !err_msg)    *err_msg = kerberos_error_string (rc);  return rc;}intdo_krb4_login (int infd, struct auth_data *ap, const char **err_msg){  int rc;  char instance[INST_SZ], version[VERSION_SZ];  long authopts = 0L;		/* !mutual */  struct sockaddr_in faddr;  u_char auth_buf[sizeof (AUTH_DAT)];  u_char tick_buf[sizeof (KTEXT_ST)];  Key_schedule schedule;  AUTH_DAT *kdata;  KTEXT ticket;  struct passwd *pwd;    kdata = (AUTH_DAT *) auth_buf;  ticket = (KTEXT) tick_buf;  instance[0] = '*';  instance[1] = '\0';#ifdef ENCRYPTION  if (encrypt_io)    {      rc = sizeof faddr;      if (getsockname (0, (struct sockaddr *) &faddr, &rc))	{	  *err_msg = "getsockname failed";	  syslog (LOG_ERR, "getsockname failed: %m");	  return 1;	}      authopts = KOPT_DO_MUTUAL;      rc = krb_recvauth (authopts, 0,			 ticket, "rcmd",			 instance, &ap->from, &faddr,			 kdata, "", schedule, version);      des_set_key (kdata->session, schedule);    }  else#endif    rc = krb_recvauth (authopts, 0,		       ticket, "rcmd",		       instance, &ap->from, NULL,		       kdata, "", NULL, version);  if (rc != KSUCCESS)    return 1;    getstr (infd, &ap->lusername, NULL);  /* get the "cmd" in the rcmd protocol */  getstr (infd, &ap->term, "TERM=");  pwd = getpwnam (ap->lusername);  if (pwd == NULL)    {      *err_msg = "getpwnam failed";      syslog (LOG_ERR, "getpwnam failed: %m");      return 1;    }  /* returns nonzero for no access */  if (kuserok (kdata, ap->lusername) != 0)    return 1;  if (pwd->pw_uid == 0)    syslog (LOG_INFO | LOG_AUTH,	    "ROOT Kerberos login from %s.%s@%s on %s\n",	    kdata->pname, kdata->pinst, kdata->prealm, ap->hostname);  else    syslog (LOG_INFO | LOG_AUTH,	    "%s Kerberos login from %s.%s@%s on %s\n",	    pwd->pw_name,	    kdata->pname, kdata->pinst, kdata->prealm, ap->hostname);  return 0;}#ifdef KERBEROS_Vintdo_krb5_login (int infd, struct auth_data *ap, const char **err_msg){  krb5_auth_context auth_ctx = NULL;  krb5_error_code status;  krb5_data inbuf;  krb5_data version;  krb5_authenticator *authenticator;  krb5_rcache rcache;  krb5_keyblock *key;  krb5_ticket *ticket;  struct sockaddr_in laddr;  int len;  struct passwd *pwd;  char *name;  if (status = krb5_init_context (&ap->context))    {      syslog (LOG_ERR, "Error initializing krb5: %s",	      error_message (status));      return status;    }  if ((status = krb5_auth_con_init (ap->context, &auth_ctx))      || (status = krb5_auth_con_genaddrs (ap->context, auth_ctx, infd,			     KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))      || (status = krb5_auth_con_getrcache (ap->context, auth_ctx, &rcache)))    return status;  if (!rcache)    {      krb5_principal server;      status = krb5_sname_to_principal (ap->context, 0, 0, KRB5_NT_SRV_HST,					&server);      if (status)	return status;            status =  krb5_get_server_rcache (ap->context,			    krb5_princ_component (ap->context, server, 0),	                    &rcache);      krb5_free_principal(ap->context, server);            if (status)	return status;            status = krb5_auth_con_setrcache (ap->context, auth_ctx, rcache);      if (status)	return status;    }  len = sizeof (laddr);  if (getsockname (infd, (struct sockaddr *)&laddr, &len))    return errno;  status = krb5_recvauth (ap->context, &auth_ctx, &infd, NULL, 0,			  0, ap->keytab, &ticket);  if (status)    return status;  if ((status = krb5_auth_con_getauthenticator (ap->context, auth_ctx,						&authenticator)))    return status;    getstr (infd, &ap->lusername, NULL);  getstr (infd, &ap->term, "TERM=");    pwd = getpwnam (ap->lusername);  if (pwd == NULL)    {      *err_msg = "getpwnam failed";      syslog (LOG_ERR, "getpwnam failed: %m");      return 1;    }    getstr (infd, &ap->rusername, NULL);  if ((status = krb5_copy_principal(ap->context,				    ticket->enc_part2->client,				    &ap->client)))    return status;        /*OK::*/  if (ap->client && !krb5_kuserok (ap->context, ap->client, ap->lusername))    return 1;  krb5_unparse_name (ap->context, ap->client, &name);    syslog (LOG_INFO | LOG_AUTH,	  "%sKerberos V login from %s on %s\n",	  (pwd->pw_uid == 0) ? "ROOT " : "",	  name, ap->hostname);  free (name);    return 0;}#endif#endif#define BUFFER_SIZE 128voidgetstr(int infd, char **ptr, const char *prefix){  char c;  char *buf;  int pos;  int size = BUFFER_SIZE;  if (prefix)    {      int len = strlen(prefix);      if (size < len + 1)	size = len + 1;    }  buf = malloc (size);  if (!buf)    {      syslog (LOG_ERR, "not enough memory");      exit (1);    }  pos = 0;  if (prefix)    {      strcpy (buf, prefix);      pos += strlen (buf);    }  do    {      if (read (infd, &c, 1) != 1)	{	  syslog (LOG_ERR, "read error: %m");	  exit (1);	}      if (pos == size)	{	  size += BUFFER_SIZE;	  buf = realloc (buf, size);	  if (!buf)	    {	      syslog (LOG_ERR, "not enough memory");	      exit (1);	    }	}      buf[pos++] = c;    }  while (c != 0);  *ptr = buf;}#define	pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))char magic[2] = {0377, 0377};char oobdata[] = {TIOCPKT_WINDOW}; /* May be modified by protocol/control */voidprotocol (int f, int p){  char fibuf[1024], *pbp = NULL, *fbp = NULL;  int pcc = 0, fcc = 0;  int cc, nfd, n;  char cntl;#ifdef TIOCPKT  int tiocpkt_on = 0;#endif  /*   * Must ignore SIGTTOU, otherwise we'll stop   * when we try and set slave pty's window shape   * (our controlling tty is the master pty).   */  signal (SIGTTOU, SIG_IGN);  send (f, oobdata, 1, MSG_OOB);	/* indicate new rlogin */  if (f > p)    nfd = f + 1;  else    nfd = p + 1;  if (nfd > FD_SETSIZE)    {      syslog (LOG_ERR, "select mask too small, increase FD_SETSIZE");      fatal (f, "internal error (select mask too small)", 0);    }  while (1)    {      fd_set ibits, obits, ebits, *omask;      FD_ZERO (&ebits);      FD_ZERO (&ibits);      FD_ZERO (&obits);      omask = (fd_set *) NULL;      if (fcc)	{	  FD_SET (p, &obits);	  omask = &obits;	}      else	FD_SET (f, &ibits);      if (pcc >= 0)	{	  if (pcc)	    {	      FD_SET (f, &obits);	      omask = &obits;	    }	  else	    FD_SET (p, &ibits);	}      FD_SET (p, &ebits);      if ((n = select (nfd, &ibits, omask, &ebits, 0)) < 0)	{	  if (errno == EINTR)	    continue;	  fatal (f, "select", 1);	}      if (n == 0)	{	  /* shouldn't happen... */	  sleep (5);	  continue;	}      if (FD_ISSET (p, &ebits))	{	  cc = read (p, &cntl, 1);	  if (cc == 1 && pkcontrol (cntl))	    {	      cntl |= oobdata[0];	      send (f, &cntl, 1, MSG_OOB);	      if (cntl & TIOCPKT_FLUSHWRITE)		{		  pcc = 0;		  FD_CLR (p, &ibits);		}	    }	}      if (FD_ISSET (f, &ibits))	{	  ENC_READ (fcc, f, fibuf, sizeof (fibuf));	  if (fcc < 0 && errno == EWOULDBLOCK)	    fcc = 0;	  else	    {	      register char *cp;	      int left;	      if (fcc <= 0)		break;	      fbp = fibuf;	      for (cp = fibuf; cp < fibuf + fcc - 1; cp++)		if (cp[0] == magic[0] && cp[1] == magic[1])		  {		    int len;		    left = fcc - (cp - fibuf);		    len = control (p, cp, left);		    if (len)		      {			left -= len;			if (left > 0)			  memmove (cp, cp + len, left);			fcc -= len;			cp--;		      }		  }	      FD_SET (p, &obits);	/* try write */	    }	}      if (FD_ISSET (p, &obits) && fcc > 0)	{	  cc = write (p, fbp, fcc);	  if (cc > 0)	    {	      fcc -= cc;	      fbp += cc;	    }	}      if (FD_ISSET (p, &ibits))	{	  char dbuf[1024 + 1];	  pcc = read (p, dbuf, sizeof dbuf);	  pbp = dbuf;	  if (pcc < 0)	    {	      if (errno == EWOULDBLOCK)		pcc = 0;	      else		break;	    }	  else if (pcc == 0)	    {	      break;	    }	  else if (dbuf[0] == 0)	    {	      pbp++;	      pcc--;	      IF_NOT_ENCRYPT (FD_SET (f, &obits));	/* try write */	    }	  else	    {	      if (pkcontrol (dbuf[0]))		{		  dbuf[0] |= oobdata[0];		  send (f, &dbuf[0], 1, MSG_OOB);		}	      pcc = 0;	    }	}      if ((FD_ISSET (f, &obits)) && pcc > 0)	{	  ENC_WRITE (cc, f, pbp, pcc);	  if (cc < 0 && errno == EWOULDBLOCK)	    {	      /*	       * This happens when we try write after read	       * from p, but some old kernels balk at large	       * writes even when select returns true.	       */	      if (!FD_ISSET (p, &ibits))		sleep (5);	      continue;	    }	  if (cc > 0)	    {	      pcc -= cc;	      pbp += cc;	    }	}    }}/* Handle a "control" request (signaled by magic being present)   in the data stream.  For now, we are only willing to handle   window size changes. */intcontrol (int pty, char *cp, size_t n){  struct winsize w;  if (n < 4 + sizeof (w) || cp[2] != 's' || cp[3] != 's')    return (0);  oobdata[0] &= ~TIOCPKT_WINDOW;	/* we know he heard */  memmove (&w, cp + 4, sizeof w);  w.ws_row = ntohs (w.ws_row);  w.ws_col = ntohs (w.ws_col);  w.ws_xpixel = ntohs (w.ws_xpixel);  w.ws_ypixel = ntohs (w.ws_ypixel);  ioctl (pty, TIOCSWINSZ, &w);  return (4 + sizeof w);}RETSIGTYPEcleanup (int signo){  char *p;  (void)signo;  p = line + sizeof (PATH_DEV) - 1;#ifdef UTMPX  utmp_logout (p);  chmod (line, 0644);  chown (line, 0, 0);#else  if (logout (p))    logwtmp (p, "", "");  chmod (line, 0666);  chown (line, 0, 0);  *p = 'p';  chmod (line, 0666);  chown (line, 0, 0);#endif  shutdown (netf, 2);  exit (1);}intin_local_domain (char *hostname){  char *p = topdomain (hostname, local_dot_count);  return p && strcasecmp (p, local_domain_name) == 0;}char *topdomain (char *name, int max_dots){  char *p;  int dot_count = 0;  for (p = name + strlen (name) - 1; p >= name; p--)    {      if (*p == '.' && ++dot_count == max_dots)	return p + 1;    }  return name;}voidfatal (int f, const char *msg, int syserr){  int len;  char buf[BUFSIZ], *bp = buf;  /*   * Prepend binary one to message if we haven't sent   * the magic null as confirmation.   */  if (!confirmed)    *bp++ = '\01';		/* error indicator */  if (syserr)    snprintf (bp, sizeof buf - (bp - buf),	      "rlogind: %s: %s.\r\n", msg, strerror (errno));  else    snprintf (bp, sizeof buf - (bp - buf), "rlogind: %s.\r\n", msg);  len = strlen (bp);  write (f, buf, bp + len - buf);  exit (1);}static const char usage_str[] ="usage: rlogind [options]\n""\n""Options are:\n""   -a, --verify-hostname   Ask hostname for verification\n""   -d, --daemon            Daemon mode\n""   -l, --no-rhosts         Ignore .rhosts file\n""   -L, --local-domain=NAME Set local domain name\n""   -n, --no-keepalive      Do not set SO_KEEPALIVE\n"#ifdef KERBEROS"   -k, --kerberos          Use kerberos IV authentication\n"#ifdef ENCRYPTION"   -x, --encrypt           Use DES encryption\n"#endif /* ENCRYPTION */#endif /* KERBEROS */"   -D, --debug[=LEVEL]     Set debug level\n""   -h, --help              Display usage instructions\n""   -V, --version           Display program version\n""   -o, --allow-root        Allow uid == 0 to login, disable by default\n""   -p, --port PORT         Listen on given port (valid only in daemon mode)\n""   -r, --reverse-required  Require reverse resolving of a remote host IP\n";voidusage(){  printf ("%s\n"	 "Send bug reports to %s\n",	 usage_str, PACKAGE_BUGREPORT);}int volatile _st;stop(){	for (_st=0; !_st;)		_st=_st;}

⌨️ 快捷键说明

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