	     README for mdidentd v0.85.3
	    -----------------------------
	    
* What is it?
------------------

Mdidentd is a special ident daemon that permits processes to set their
own fake ident replies regardless of the userid they are running 
under.

The major advantage of using mdidentd is that you are not forced to replace your 
existing ident daemon with mine. That is, mdidentd works together with your 
existing ident daemon so that you get the features of mdidentd AND any special 
features your existing identd may offer (provided that it designed to be spawned
from inetd).

Mdidentd was written by Murat Deligonul (druglord@erupt.com)


* How it works 
----------------------

* The server listens on tcp port 113 (the standard auth port) and on the a
 domain socket residing by default at /var/run/mdidentd
 
* Programs register fake idents through the domain socket.

* When mdidentd receives an ident request, it first checks its internal
 list of fake idents and replies with the fake one if a match is found.
 If no match is found, the user's other ident daemon is spawned to handle
 the request.
 
* Repeat steps 2-4.


* How do I build it?
----------------------

Mdidentd is not currently distributed in a stand alone package.
So you have probably obtained it with ezbounce. You will need to run 
./configure from the top level ezbounce directory and then cd to the 
mdidentd dir and type make.

Typing make install will copy mdidentd to /usr/local/sbin

You'll need a C++ compiler. GCC 2.7.2.1 and above will work.


* How do I install it?
-----------------------

You first need to disable your existing inetd-based ident daemon.
To do so, open /etc/inetd.conf. Find the line starting with
'auth':

auth   stream  tcp     nowait    nobody    /usr/sbin/in.identd in.identd -l -e -o

That is how it is appears on my system. To disable it you will
need to add '#' character to the beginning of the line. But *don't*
add a line to make it run mdidentd. Also notice the last part that
 says '/usr/sbin/in.identd in.identd -l -e -o'. Make a note of it, 
 because you will need to use it again soon.

Save the file, exit your editor, and do:

killall -HUP inetd

Now, run mdidentd. Im assuming you have built it. On my system i do:

/usr/local/sbin/mdidentd /usr/sbin/in.identd -l -e -o

The first argument, the path to in.identd is required. The rest are optional. 
You may or may not need to supply them, and the ones you need to supply may be 
different for your system. Also note that in the line in /etc/inetd.conf, the
path to in.identd was proceeded with another 'in.identd'. You can get rid of it.
And in the example above to spawn mdidentd, it's not there. 

If you are using ezbounce, you will need to configure it to
use mdidentd for fake idents. 
To do this, open up your ezbounce configuration file and stick
the following lines in:

set enable-fake-idents 1
set auto-fake-idents 1

Ezbounce will need to be restarted or issued the 'rehash'
command it if is already running.

The final step is making sure mdidentd will run after a reboot.
This can be done by putting the command to launch it
(see above) in your rc.local file (which usually resides
in /etc/rc.d).

Note that mdidentd will need to be run as root (or setuid root). It binds to
port 113, a privilaged port, and creates a unix domain socket in
/var/run/mdidentd. There is a command line option you can use to make
ezbounce become a different user once it has created these resources. See below.


* Other command line options
------------------------------

The syntax for passing command line options to mdidentd is:

mdidentd [-f|-k|-h|-u] <identd> [options]

And here is what they mean:

-f:		Stay in the foreground. Do not fork and go into the background

-k:		Automatically delete fake ident requests after they have been
		replied to. Basically, mdidentd stores the fake ident requests
		in memory, and they remain there for 30 seconds until they
		are destroyed. With this option, they will still be destroyed
		after 30 seconds, but they can freed sooner if an ident
		request matching it is recieved. It is probably a good idea
		to use this.

-u <uid>:	Become this user after binding to port 113. Again, probably
		a good idea as well, especially if you, for some reason, don't 
		trust my code ;) The uid needs to be a numeric id, you can't
		 use something like 'nobody'. If you don't know the numeric id 
		 for a user, try 'id user'.

-h <number>:	Set a limit on the number of fake idents that will be stored.
		This is basically to prevent abuse. By default it is at 200,
		which i think is more than enough. It will depend on your needs;
		if there a 1000 people on your system trying to IRC without
		using their real idents maybe you should increase the limit
		to that :)
		
-r:		This prevents people from setting fake idents that happen
		to be names of valid users on the system.

<identd>	The path to an ident daemon. It MUST be something inetd-based,
		that is, something that will work with inetd. For most people 
		it will be simply the path of the ident daemon that was listed 
		in their inetd.conf file.

[options]	Any additional command line options you want to pass to the
		ident daemon mentioned above.


* Utilizing mdidentd & fake idents in your own programs
--------------------------------------------------------

I've included a cheesy little library, lib_mdidentd.c (and lib_mdidentd.h),
residing in the lib/ directory, that provides an interface for creating fake
ident requests from your own programs. The library is so complex in fact,
that it has only two functions.

PROTOTYPE

int register_fake_ident(const char * path, const char * ident,
                   unsigned short local_port, unsigned short remote_port)

DESCRIPTION

   This connects to the mdidentd daemon and registers a fake ident request

   path         - where the domain socket of mdidentd resides. Just use 
		   MDIDENTD_PATH
   ident        - what you want the fake ident to be
   local_port   - local port
   remote_port  - port you're connecting to.

 Every thing should be fairly obvious except maybe local_port. If you don't
know how to obtain it, try binding the socket to a local interface before 
connecting, and calling getsockname on it. Example:
   
    struct sockaddr_in sin, sin2;
    int s,x = sizeof(struct sockaddr_in); 
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return 0;
    memset(&sin, 0, sizeof(sin));
    
    /* Fill this with zeroes -- basically means we want to
       bind to the default interface on the box */
    memcpy(&sin.sin_addr, 0, sizeof(sin.sin_addr));
    sin.sin_family = AF_INET;
    if ((bind(s, (const struct sockaddr *) &sin, sizeof(sin)) < 0))
	return 0;
   
    getsockname(s, (struct sockaddr *) &sin2, &x);
    x = register_fake_ident(MDIDENTD_PATH, "fake0007", 
	ntohs(sin2.sin_port), port);
     /* ^^^^ local port right there */
     
    /* Connect now */


RETURN VALUE:

   1 on success. 0 or less on error. Possible error return values below:

    switch (err)
    {
    case IDENT_ERROR_INVAL:
        return "Invalid ident request given";
    case IDENT_ERROR:
        return "Unknown error";
    case IDENT_ERROR_EXISTS:
        return "Ident request already exists";
    case IDENT_CONNECT_FAILURE:
        return "Error connecting to domain socket";
    case IDENT_AUTH_FAILURE:
        return "Authorization denied (possibly bad ident request)";
    }
    
   This is the bulk of the ident_error(int err) function. Just give
   it the return value from register_fake_ident().


* What does the name mean?
--------------------------

This program was unnamed for a while. After going through
all 26 letters of the English alphabet and trying 
[letter]identd, i realized that:

* The cool names were already taken
* Some names were ambigious and/or would cause confusion.
* A lot of the names just sounded plain silly

So i chose to use my initials. I am open to suggestions for a better or 
simpler name.


* Other things
---------------

Fake ident requests for 'root' are not allowed.
In the future i might add support for a configuration file that will store
lists of idents people are not allowed to set.

Look in defs.h for some constants that control how long fake ident requests 
live, and how long to wait on connections before they timeout.

Is mdidentd compliant with identd rfc (whatever number it is)?  I don't 
know either.

Both mdidentd and its author are believed to be Y2K compliant.
