
/*
 * fake ident server 0.2 by zed@linuxpower.org - replies to 1 request and exits.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <pwd.h>
#include <sys/types.h>

int
main(int argc, char *argv[])
{
   int sok, read_sok, len, res;
   char *p;
   char buf[256];
   char outbuf[256];
   struct passwd *pw;
   /*struct hostent *ha;*/
   struct sockaddr_in addr;

   pw = getpwnam ("nobody");
   if (!pw)
   {
      printf ("%% user \"nobody\" doesn't exist.\n");
      return 0;
   }

   seteuid (pw->pw_uid);    /* drop root priv. */

   if (argc < 2)
   {
      printf ("%s <username>\n", argv[0]);
      return 0;
   }

   if (argv[1] == NULL)    /* this is impossible right? */
      return 0;

   if (strlen (argv[1]) > 63)
      return 0;

   sok = socket (AF_INET, SOCK_STREAM, 0);
   if (sok == -1)
      return 0;

   len = 1;
   setsockopt(sok, SOL_SOCKET, SO_REUSEADDR, &len, sizeof (len));

   memset (&addr, 0, sizeof (addr));
   addr.sin_family = AF_INET;
   addr.sin_port = htons (113);

   seteuid (0);            /* regain root priv. */
   res = bind (sok, (struct sockaddr *) &addr, sizeof (addr));
   setuid (pw->pw_uid);    /* drop root priv. */
   if (res != 0)
   {
      /* inetd is probably using 113, so let's exit quietly */
      /*printf ("%% bind() failed, errno=%d\n", errno);*/
      close (sok);
      return 0;
   }

   if (listen (sok, 1) == -1)
   {
      printf ("%% listen() failed, errno=%d\n", errno);
      close (sok);
      return 0;
   }

   len = sizeof (addr);
   read_sok = accept (sok, (struct sockaddr *) &addr, &len);
   close (sok);
   if (read_sok == -1)
   {
      printf ("%% accept() failed\n");
      return 0;
   }

   /* reverse lookup the connector */
	/*ha = gethostbyaddr ((char *)&addr.sin_addr,
	                    sizeof (addr.sin_addr), addr.sin_family);
   if (ha)
   {
      printf ("%% Servicing ident request from %s (%s)\n", 
              ha->h_name,
              inet_ntoa (addr.sin_addr));
   } else
   {*/
      printf ("%% Servicing ident request from %s\n", 
              inet_ntoa (addr.sin_addr));
   /*}*/

   recv (read_sok, buf, sizeof (buf) - 1, 0);
   buf[sizeof (buf) - 1] = 0;     /* ensure null termination */

   p = strchr (buf, ',');
   if (p)
   {
      snprintf (outbuf, sizeof (outbuf) - 1, "%d, %d : USERID : UNIX : %s\r\n",
                atoi (buf), atoi (p + 1), argv[1]);
      outbuf[sizeof (outbuf) - 1] = 0;     /* ensure null termination */
      send (read_sok, outbuf, strlen (outbuf), 0);
		printf ("%% Reply: %s", outbuf);
   }

   sleep (1);

   close (read_sok);

   return 0;
}

