Beispiel #1
0
static int
print_cred(krb5_context context, krb5_creds *cred)
{
    char t1[128], t2[128], *str;
    krb5_error_code ret;
    krb5_timestamp sec;

    krb5_timeofday (context, &sec);

    if(cred->times.starttime)
	krb5_format_time(context, cred->times.starttime, t1, sizeof(t1), 1);
    else
	krb5_format_time(context, cred->times.authtime, t1, sizeof(t1), 1);

    if(cred->times.endtime > sec)
	krb5_format_time(context, cred->times.endtime, t2, sizeof(t2), 1);
    else
	strlcpy(t2, ">>>Expired<<<", sizeof(t2));

    ret = krb5_unparse_name (context, cred->server, &str);
    if (ret) {
	lreply(500, "krb5_unparse_name: %d", ret);
	return 1;
    }

    lreply(200, "%-20s %-20s %s", t1, t2, str);
    free(str);
    return 0;
}
Beispiel #2
0
void
statfilecmd (const char *filename)
{
  FILE *fin;
  int c;
  char line[LINE_MAX];

  snprintf (line, sizeof (line), "/bin/ls -lgA %s", filename);
  fin = ftpd_popen (line, "r");
  lreply (211, "status of %s:", filename);
  while ((c = getc (fin)) != EOF)
    {
      if (c == '\n')
	{
	  if (ferror (stdout))
	    {
	      perror_reply (421, "control connection");
	      ftpd_pclose (fin);
	      dologout (1);
	    }
	  if (ferror (fin))
	    {
	      perror_reply (551, filename);
	      ftpd_pclose (fin);
	      return;
	    }
	  putc ('\r', stdout);
	}
      putc (c, stdout);
    }
  ftpd_pclose (fin);
  reply (211, "End of Status");
}
Beispiel #3
0
static int
klist5(void)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_ccache ccache;
    krb5_principal principal;
    int exit_status = 200;

    ret = krb5_init_context (&context);
    if (ret) {
	lreply(500, "krb5_init_context failed: %d", ret);
	return 500;
    }

    if (k5ccname)
	ret = krb5_cc_resolve(context, k5ccname, &ccache);
    else
	ret = krb5_cc_default (context, &ccache);
    if (ret) {
	lreply(500, "krb5_cc_default: %d", ret);
	return 500;
    }

    ret = krb5_cc_get_principal (context, ccache, &principal);
    if (ret) {
	if(ret == ENOENT)
	    lreply(500, "No ticket file: %s",
		   krb5_cc_get_name(context, ccache));
	else
	    lreply(500, "krb5_cc_get_principal: %d", ret);

	return 500;
    }
    exit_status = print_tickets (context, ccache, principal);

    ret = krb5_cc_close (context, ccache);
    if (ret) {
	lreply(500, "krb5_cc_close: %d", ret);
	exit_status = 500;
    }

    krb5_free_principal (context, principal);
    krb5_free_context (context);
    return exit_status;
}
Beispiel #4
0
static int
print_tickets (krb5_context context,
	       krb5_ccache ccache,
	       krb5_principal principal)
{
    krb5_error_code ret;
    krb5_cc_cursor cursor;
    krb5_creds cred;
    char *str;

    ret = krb5_unparse_name (context, principal, &str);
    if (ret) {
	lreply(500, "krb5_unparse_name: %d", ret);
	return 500;
    }

    lreply(200, "%17s: %s:%s",
	   "Credentials cache",
	   krb5_cc_get_type(context, ccache),
	   krb5_cc_get_name(context, ccache));
    lreply(200, "%17s: %s", "Principal", str);
    free (str);

    ret = krb5_cc_start_seq_get (context, ccache, &cursor);
    if (ret) {
	lreply(500, "krb5_cc_start_seq_get: %d", ret);
	return 500;
    }

    lreply(200, "  Issued               Expires              Principal");

    while ((ret = krb5_cc_next_cred (context,
				     ccache,
				     &cursor,
				     &cred)) == 0) {
	if (print_cred(context, &cred))
	    return 500;
	krb5_free_cred_contents (context, &cred);
    }
    if (ret != KRB5_CC_END) {
	lreply(500, "krb5_cc_get_next: %d", ret);
	return 500;
    }
    ret = krb5_cc_end_seq_get (context, ccache, &cursor);
    if (ret) {
	lreply(500, "krb5_cc_end_seq_get: %d", ret);
	return 500;
    }

    return 200;
}
Beispiel #5
0
int
display_file (const char *name, int code)
{
  char *cp, line[LINE_MAX];
  FILE *fp = fopen (name, "r");
  if (fp != NULL)
    {
      while (fgets (line, sizeof(line), fp) != NULL)
	{
	  cp = strchr (line, '\n');
	  if (cp != NULL)
	    *cp = '\0';
	  lreply (code, "%s", line);
	}
      (void) fflush (stdout);
      (void) fclose (fp);
      return 0;
    }
  return errno;
}
Beispiel #6
0
static void
complete_login (struct credentials *pcred)
{
  if (setegid ((gid_t) pcred->gid) < 0)
    {
      reply (550, "Can't set gid.");
      return;
    }

#ifdef HAVE_INITGROUPS
  initgroups (pcred->name, pcred->gid);
#endif

  /* open wtmp before chroot */
  snprintf (ttyline, sizeof (ttyline), "ftp%d", getpid ());
  logwtmp_keep_open (ttyline, pcred->name, pcred->remotehost);

  if (pcred->guest)
    {
      /* We MUST do a chdir () after the chroot. Otherwise
         the old current directory will be accessible as "."
         outside the new root!  */
      if (chroot (pcred->rootdir) < 0 || chdir (pcred->homedir) < 0)
	{
	  reply (550, "Can't set guest privileges.");
	  goto bad;
	}
    }
  else if (pcred->dochroot)
    {
      if (chroot (pcred->rootdir) < 0 || chdir (pcred->homedir) < 0)
	{
	  reply (550, "Can't change root.");
	  goto bad;
	}
      setenv ("HOME", pcred->homedir, 1);
    }
  else if (chdir (pcred->rootdir) < 0)
    {
      if (chdir ("/") < 0)
	{
	  reply (530, "User %s: can't change directory to %s.",
		 pcred->name, pcred->homedir);
	  goto bad;
	}
      else
	lreply (230, "No directory! Logging in with home=/");
    }

  if (seteuid ((uid_t) pcred->uid) < 0)
    {
      reply (550, "Can't set uid.");
      goto bad;
    }

  /* Display a login message, if it exists.
     N.B. reply(230,) must follow the message.  */
  display_file (PATH_FTPLOGINMESG, 230);

  if (pcred->guest)
    {
      reply (230, "Guest login ok, access restrictions apply.");
#ifdef HAVE_SETPROCTITLE
      snprintf (proctitle, sizeof (proctitle), "%s: anonymous",
		pcred->remotehost);
      setproctitle ("%s", proctitle);
#endif /* HAVE_SETPROCTITLE */
      if (logging)
	syslog (LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s", pcred->remotehost);
    }
  else
    {
      reply (230, "User %s logged in.", pcred->name);
#ifdef HAVE_SETPROCTITLE
      snprintf (proctitle, sizeof (proctitle),
		"%s: %s", pcred->remotehost, pcred->name);
      setproctitle ("%s", proctitle);
#endif /* HAVE_SETPROCTITLE */
      if (logging)
	syslog (LOG_INFO, "FTP LOGIN FROM %s as %s",
		pcred->remotehost, pcred->name);
    }
  umask (defumask);
  return;
bad:
  /* Forget all about it... */
  end_login (pcred);
}
Beispiel #7
0
void
statcmd (void)
{
  struct sockaddr_in *sin;
  u_char *a, *p;

  lreply (211, "%s FTP server status:", hostname);
  if (!no_version)
    printf ("     ftpd (%s) %s\r\n", PACKAGE_NAME, PACKAGE_VERSION);
  printf ("     Connected to %s", cred.remotehost);
  if (!isdigit (cred.remotehost[0]))
    printf (" (%s)", inet_ntoa (his_addr.sin_addr));
  printf ("\r\n");
  if (cred.logged_in)
    {
      if (cred.guest)
	printf ("     Logged in anonymously\r\n");
      else
	printf ("     Logged in as %s\r\n", cred.name);
    }
  else if (askpasswd)
    printf ("     Waiting for password\r\n");
  else
    printf ("     Waiting for user name\r\n");
  printf ("     TYPE: %s", typenames[type]);
  if (type == TYPE_A || type == TYPE_E)
    printf (", FORM: %s", formnames[form]);
  if (type == TYPE_L)
#ifdef CHAR_BIT
    printf (" %d", CHAR_BIT);
#else
# if NBBY == 8
    printf (" %d", NBBY);
# else
    printf (" %d", bytesize);	/* need definition! */
# endif
#endif
  printf ("; STRUcture: %s; transfer MODE: %s\r\n",
	  strunames[stru], modenames[stru_mode]);
  if (data != -1)
    printf ("     Data connection open\r\n");
  else if (pdata != -1)
    {
      printf ("     in Passive mode");
      sin = &pasv_addr;
      goto printaddr;
    }
  else if (usedefault == 0)
    {
      printf ("     PORT");
      sin = &data_dest;
    printaddr:
      a = (u_char *) & sin->sin_addr;
      p = (u_char *) & sin->sin_port;
#define UC(b) (((int) b) & 0xff)
      printf (" (%d,%d,%d,%d,%d,%d)\r\n", UC (a[0]),
	      UC (a[1]), UC (a[2]), UC (a[3]), UC (p[0]), UC (p[1]));
#undef UC
    }
  else
    printf ("     No data connection\r\n");
  reply (211, "End of status");
}
Beispiel #8
0
/* Transfer data from peer to "outstr" using the appropriate encapulation of
   the data subject to Mode, Structure, and Type.

   N.B.: Form isn't handled.  */
static int
receive_data (FILE * instr, FILE * outstr)
{
  int c;
  int cnt, bare_lfs = 0;
  char buf[BUFSIZ];

  transflag++;
  if (setjmp (urgcatch))
    {
      transflag = 0;
      return -1;
    }
  switch (type)
    {
    case TYPE_I:
    case TYPE_L:
      while ((cnt = read (fileno (instr), buf, sizeof (buf))) > 0)
	{
	  if (write (fileno (outstr), buf, cnt) != cnt)
	    goto file_err;
	  byte_count += cnt;
	}
      if (cnt < 0)
	goto data_err;
      transflag = 0;
      return 0;

    case TYPE_E:
      reply (553, "TYPE E not implemented.");
      transflag = 0;
      return -1;

    case TYPE_A:
      while ((c = getc (instr)) != EOF)
	{
	  byte_count++;
	  if (c == '\n')
	    bare_lfs++;
	  while (c == '\r')
	    {
	      if (ferror (outstr))
		goto data_err;
	      c = getc (instr);
	      if (c != '\n')
		{
		  putc ('\r', outstr);
		  if (c == '\0' || c == EOF)
		    goto contin2;
		}
	    }
	  putc (c, outstr);
	contin2:;
	}
      fflush (outstr);
      if (ferror (instr))
	goto data_err;
      if (ferror (outstr))
	goto file_err;
      transflag = 0;
      if (bare_lfs)
	{
	  lreply (226, "WARNING! %d bare linefeeds received in ASCII mode",
		  bare_lfs);
	  printf ("   File may not have transferred correctly.\r\n");
	}
      return (0);
    default:
      reply (550, "Unimplemented TYPE %d in receive_data", type);
      transflag = 0;
      return -1;
    }

data_err:
  transflag = 0;
  perror_reply (426, "Data Connection");
  return -1;

file_err:
  transflag = 0;
  perror_reply (452, "Error writing file");
  return -1;
}