Here we are with the fifth installment of the LDAP authentication module.
Everything is now implemented except for the change_password routine
because that needs a lot more work.

This version also has no apparent memory leaks, checked with the excellent
ccmalloc tool, http://www.inf.ethz.ch/personal/biere/projects/ccmalloc/

At this point, I'd like to ask the IC&S folks to include authldap.c with
the dbmail distribution. Please let me know the status of getting into the
next release, either a point release or a minor version bump.

As for my discussion of the aliases table, for now I'm not worrying about
it. The auth_check_user routine actually take an email address as
an argument (desprite the function and the variable both calling it a
'username'... and so that works to find the user by their 'aliases' in the
ldap (the FIELD_MAIL and FIELD_MAILALT, equally). Additionally, the
aliases are only tied to a specific user if the deliver_to field is
numeric. If it is not, then the alias is pointing to an outside address or
to a program. I'm not sure if these should go into the directory, or stay
in the database... if anybody cares, we should start a thread on my
previous mailings and figure out a good way to handle this!

Here's the necessary config file section, just drop it into
/etc/dbmail.conf and customize as needed (this one works with the
qmail-ldap patch, at http://nrg4u.com):

[LDAP]
BASE_DN=ou=Users,dc=Acme,dc=Com
BIND_DN=cn=Manager,dc=Acme,dc=Com
BIND_PW=secret
SCOPE=SubTree
PORT=389
HOSTNAME=localhost
OBJECTCLASS=qmailuser
FIELD_UID=uid
FIELD_CID=qmailgid
FIELD_NID=qmailuid
FIELD_MAIL=mail
FIELD_MAILALT=mailalternateaddress
FIELD_QUOTA=mailquota


Aaron
/*
 * authtest.c
 *
 * Conformance tests for authentication modules
 *
 * (c) 2002 Aaron Stone
 *
 * Procedure:
 * - Connect to the authentication provider
 * - Generate some user information (could be DEFINE'd, or rand() or whatever)
 * - Check if a user by this name and/or number exists (don't clobber!)
 * - Create a user with the information we have secured
 * - Get the user's information:
 *   User ID
 *   Client ID
 *   Max Mail Size
 *   Encryption Type
 * - Authenticate with the user data
 * - Change the user's information:
 *   Password
 *   Username
 *   Client ID
 *   Mailbox Size
 * - Authenticate again with the new user data
 * - Get a list of all known users:
 *   Make sure that the test user is in there
 * - Delete the test user
 * - Get another list of all known users:
 *   Make sure that the test user is gone
 * - Disconnect from the authentication provider
 */

#include "auth.h"
#include "list.h"
#include "debug.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>

#define MAX_CHECKS_DEPTH 1000
/* #define DBMAIL_USE_SAME_CONNECTION */
/* #define _DBAUTH_STRICT_USER_CHECK */

char *configFile = "/etc/dbmail.conf";
int TRACE_TO_SYSLOG = 1;

int main()
{
        int ret_int;
        char *ret_char;
        u64_t ret_u64_t;
        u64_t useridnr;

        char *username, *chng_username;
        char *password, *chng_password;
        char *enctype = "blah";
        char *clientid = "123";
        char *maxmail = "456";

        struct list userlist;
        struct element *tmp;
        

        /*
         * Set up the authentication provider's connection
         */
        printf( "Testing auth_connect()...\n" );
        ret_int = auth_connect();
        printf( "   return value is %d\n", ret_int );

        printf( "Preparing a test user account...\n" );
        username = (char *)my_malloc( 16 );
        password = (char *)my_malloc( 16 );
        do
        {
                /*
                 * Generate some testing data
                 */
                printf( "   generating fake user data...\n" );
                snprintf( username, 16, "testuser.XXXXXX" );
                snprintf( password, 16, "testpass.XXXXXX" );
                mktemp( username );
                mktemp( password );
                /* No freeing needed, we'll be dying anyhow */

                /*
                 * Make sure that the generated data is really available
                 */
                printf( "Testing auth_user_exists( \"%s\" )...\n", username );
                printf( "   testing fake user data...\n" );
        } while( auth_user_exists( username ) != 0 );
        printf( "   fake data confirmed!\n" );

        printf( "Testing auth_adduser( \"%s\", \"%s\", \"%s\", \"%s\", \"%s\" 
)...\n",
                        username, password, enctype, clientid, maxmail );
        ret_u64_t = auth_adduser( username, password, enctype, clientid, 
maxmail );
        if( ret_u64_t != -1 )
        {
                useridnr = ret_u64_t;
                printf( "   user created with useridnr %llu\n", useridnr );
        }
        else
        {
                printf( "   user was NOT created\n" );
                // return 0
        }

        printf( "Testing auth_getclientid( \"%llu\" )...\n", useridnr );
        ret_u64_t = auth_getclientid( useridnr );
        printf( "   return value is %llu\n", ret_u64_t );

        printf( "Testing auth_getmaxmailsize( \"%llu\" )...\n", useridnr );
        ret_u64_t = auth_getmaxmailsize( useridnr );
        printf( "   return value is %llu\n", ret_u64_t );

        printf( "Testing auth_getencryption( \"%llu\" )...\n", useridnr );
        ret_char = auth_getencryption( useridnr );
        printf( "   return value is %s\n", ret_char );
        if( ret_char != NULL ) /* free() doesn't like to get NULL pointers... */
                free( ret_char );

        printf( "Testing auth_get_userid( \"%llu\" )...\n", useridnr );
        ret_char = auth_get_userid( &useridnr );
        printf( "   return value is %s\n", ret_char );
        if( ret_char != NULL ) /* free() doesn't like to get NULL pointers... */
                free( ret_char );

        /* print a list of all known users */
        printf( "Testing auth_get_known_users( &userlist )...\n" );
        ret_int = auth_get_known_users( &userlist );
        printf( "   return value is %d\n", ret_int );
        printf( "   here's the list of users:\n" );
        tmp = list_getstart(&userlist);
        while (tmp)
        {
                printf("    [%s]", (char *)tmp->data);
                if( strcmp( (char *)tmp->data, username) == 0 )
                        printf(" --- test user found!\n" );
                else
                        printf("\n");
                tmp = tmp->nextnode;
        }

        if (userlist.start)
                list_freelist(&userlist.start);
        printf( "   done with listing users.\n" );

        printf( "Preparing a change user account...\n" );
        chng_username = (char *)my_malloc( 16 );
        chng_password = (char *)my_malloc( 16 );
        do
        {
                /*
                 * Generate some testing data
                 */
                printf( "   generating fake user data...\n" );
                snprintf( chng_username, 16, "chnguser.XXXXXX" );
                snprintf( chng_password, 16, "chngpass.XXXXXX" );
                mktemp( chng_username );
                mktemp( chng_password );
                /* No freeing needed, we'll be dying anyhow */

                /*
                 * Make sure that the generated data is really available
                 */
                printf( "Testing auth_user_exists( \"%s\" )...\n", 
chng_username );
                printf( "   testing fake user data...\n" );
        } while( auth_user_exists( chng_username ) != 0 );
        printf( "   fake data confirmed!\n" );

        /* let's change up the values, and test it all again */
        printf( "Testing auth_change_username( \"%llu\", \"%s\" )...\n", 
useridnr, chng_username );
        ret_int = auth_change_username( useridnr, chng_username );
        printf( "   return value is %d\n", ret_int );

        /* let's change up the values, and test it all again */
        printf( "Testing auth_change_password( \"%llu\", \"%s\", \"%s\" 
)...\n", useridnr, chng_password, enctype );
        ret_int = auth_change_password( useridnr, chng_password, enctype );
        printf( "   return value is %d\n", ret_int );

        /* let's change up the values, and test it all again */
        printf( "Testing auth_change_clientid( \"%llu\", \"%llu\" )...\n", 
useridnr, strtoull( clientid, 0, 0 ) );
        ret_int = auth_change_clientid( useridnr, strtoull( clientid, 0, 0 ) );
        printf( "   return value is %d\n", ret_int );

        /* let's change up the values, and test it all again */
        printf( "Testing auth_change_mailboxsize( \"%llu\", \"%llu\" )...\n", 
useridnr, strtoull( maxmail, 0, 0 ) );
        ret_int = auth_change_mailboxsize( useridnr, strtoull( maxmail, 0, 0 ) 
);
        printf( "   return value is %d\n", ret_int );

        /* print a list of all known users */
        printf( "Testing auth_get_known_users( &userlist )...\n" );
        ret_int = auth_get_known_users( &userlist );
        printf( "   return value is %d\n", ret_int );
        printf( "   here's the list of users:\n" );
        tmp = list_getstart(&userlist);
        while (tmp)
        {
                printf("    [%s]", (char *)tmp->data);
                if( strcmp( (char *)tmp->data, chng_username) == 0 )
                        printf(" --- test user found!\n" );
                else
                        printf("\n");
                tmp = tmp->nextnode;
        }

        if (userlist.start)
                list_freelist(&userlist.start);
        printf( "   done with listing users.\n" );

        /* delete the test user */
        printf( "Testing auth_delete_user( %s )...\n", username );
        ret_int = auth_delete_user( username );
        printf( "   return value is %d\n", ret_int );

        /* delete the test user */
        printf( "Testing auth_delete_user( %s )...\n", chng_username );
        ret_int = auth_delete_user( chng_username );
        printf( "   return value is %d\n", ret_int );

        /* disconnect from the authentication service */
        printf( "Testing auth_disconnect()...\n" );
        ret_int = auth_disconnect();
        printf( "   return value is %d\n", ret_int );

        return 0;
}

void trace (int level, char *formatstring, ...)
{
  va_list argp;
  va_start(argp, formatstring);
  fprintf (stdout, "    "); /* put some initial spacing */
  vfprintf (stdout, formatstring, argp);
  if (formatstring[strlen(formatstring)]!='\n')
    fprintf (stdout,"\n");
  va_end(argp);
}

void configure_debug(int level, int trace_syslog, int trace_verbose) { /* do 
nothing */ }

/*
int auth_check_user (const char *username, struct list *userids, int checks);
int auth_check_user_ext(const char *username, struct list *userids, struct list 
*fwds, int checks);

u64_t auth_validate (char *user, char *password);
u64_t auth_md5_validate (char *username,unsigned char *md5_apop_he, char 
*apop_stamp);
*/
/*
 * authtest.c
 *
 * Conformance tests for authentication modules
 *
 * (c) 2002 Aaron Stone
 *
 * Procedure:
 * - Connect to the authentication provider
 * - Generate some user information (could be DEFINE'd, or rand() or whatever)
 * - Check if a user by this name and/or number exists (don't clobber!)
 * - Create a user with the information we have secured
 * - Get the user's information:
 *   User ID
 *   Client ID
 *   Max Mail Size
 *   Encryption Type
 * - Authenticate with the user data
 * - Change the user's information:
 *   Password
 *   Username
 *   Client ID
 *   Mailbox Size
 * - Authenticate again with the new user data
 * - Get a list of all known users:
 *   Make sure that the test user is in there
 * - Delete the test user
 * - Get another list of all known users:
 *   Make sure that the test user is gone
 * - Disconnect from the authentication provider
 */

#include "auth.h"
#include "list.h"
#include "debug.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>

#define MAX_CHECKS_DEPTH 1000
/* #define DBMAIL_USE_SAME_CONNECTION */
/* #define _DBAUTH_STRICT_USER_CHECK */

char *configFile = "/etc/dbmail.conf";
int TRACE_TO_SYSLOG = 1;

int main()
{
        int ret_int;
        char *ret_char;
        u64_t ret_u64_t;
        u64_t useridnr;

        char *username = "";
        char *password = "";
        char *enctype = "";
        char *clientid = "";
        char *maxmail = "";

        struct list userlist;
        struct element *tmp;
        

        /*
         * Set up the authentication provider's connection
         */
        printf( "Testing auth_connect()...\n" );
        ret_int = auth_connect();
        printf( "   return value is %d\n", ret_int );

        printf( "Preparing a test user account...\n" );
        do
        {
                printf( "   generating fake user data...\n" );

                /*
                 * Generate some testing data
                 */
                /*
                 * Make sure that the generated data is really available
                 */
                printf( "Testing auth_user_exists( \"fake data\" )...\n" );
                printf( "   testing fake user data...\n" );
        } while( !auth_user_exists( "bdole" ) ); // FIXME: make this part 
actually be fake...
        printf( "   fake data confirmed!\n" );

        printf( "Testing auth_adduser( \"%s\", \"%s\", \"%s\", \"%s\", \"%s\" 
)...\n",
                        username, password, enctype, clientid, maxmail );
        ret_u64_t = auth_adduser (username, password, enctype, clientid, 
maxmail);
        if( ret_u64_t != -1 )
        {
                useridnr = ret_u64_t;
                printf( "   user created with useridnr %llu\n", useridnr );
        }
        else
        {
                printf( "   user was NOT created\n" );
                // return 0
        }

        printf( "Testing auth_getclientid( \"%llu\" )...\n", useridnr );
        ret_u64_t = auth_getclientid( useridnr );
        printf( "   return value is %llu\n", ret_u64_t );

        printf( "Testing auth_getmaxmailsize( \"%llu\" )...\n", useridnr );
        ret_u64_t = auth_getmaxmailsize( useridnr );
        printf( "   return value is %llu\n", ret_u64_t );

        printf( "Testing auth_getencryption( \"%llu\" )...\n", useridnr );
        ret_char = auth_getencryption( useridnr );
        printf( "   return value is %s\n", ret_char );
        if( ret_char != NULL ) /* free() doesn't like to get NULL pointers... */
                free( ret_char );

        printf( "Testing auth_get_userid( \"%llu\" )...\n", useridnr );
        ret_char = auth_get_userid( &useridnr );
        printf( "   return value is %s\n", ret_char );
        if( ret_char != NULL ) /* free() doesn't like to get NULL pointers... */
                free( ret_char );

        /* print a list of all known users */
        printf( "Testing auth_get_known_users( &userlist )...\n" );
        ret_int = auth_get_known_users( &userlist );
        printf( "   return value is %d\n", ret_int );
        printf( "   here's the list of users:\n" );
        tmp = list_getstart(&userlist);
        while (tmp)
        {
                printf("    [%s]\n", (char*)tmp->data);
                tmp = tmp->nextnode;
        }

        if (userlist.start)
                list_freelist(&userlist.start);
        printf( "   done with listing users.\n" );

        /* disconnect from the authentication service */
        printf( "Testing auth_disconnect()...\n" );
        ret_int = auth_disconnect();
        printf( "   return value is %d\n", ret_int );

        return 0;
}

void trace (int level, char *formatstring, ...)
{
  va_list argp;
  va_start(argp, formatstring);
  fprintf (stdout, "    "); /* put some initial spacing */
  vfprintf (stdout, formatstring, argp);
  if (formatstring[strlen(formatstring)]!='\n')
    fprintf (stdout,"\n");
  va_end(argp);
}

void configure_debug(int level, int trace_syslog, int trace_verbose) { /* do 
nothing */ }

/*
int auth_check_user (const char *username, struct list *userids, int checks);
int auth_check_user_ext(const char *username, struct list *userids, struct list 
*fwds, int checks);

int auth_delete_user(const char *username);

int auth_change_username(u64_t useridnr, const char *newname);
int auth_change_password(u64_t useridnr, const char *newpass, const char 
*enctype);
int auth_change_clientid(u64_t useridnr, u64_t newcid);
int auth_change_mailboxsize(u64_t useridnr, u64_t newsize);

u64_t auth_validate (char *user, char *password);
u64_t auth_md5_validate (char *username,unsigned char *md5_apop_he, char 
*apop_stamp);
*/

Reply via email to