Grr... both files turned out to be authtest.c, here's the real authldap.c
On Sat, 18 Jan 2003, Aaron Stone wrote:
> 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
>
/*
* $Id: authldap.c $
* (c) 2002 Aaron Stone, [EMAIL PROTECTED]
* User authentication functions for LDAP.
*/
#include "auth.h"
#include <ldap.h>
#include "list.h"
#include "debug.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "db.h"
#include "dbmd5.h"
#include <crypt.h>
#include "config.h"
#include <time.h>
#define AUTH_QUERY_SIZE 1024
extern char *configFile;
LDAP *_ldap_conn;
LDAPMod **_ldap_mod;
LDAPMessage *_ldap_res;
LDAPMessage *_ldap_msg;
int _ldap_err;
int _ldap_attrsonly = 0;
char *_ldap_dn;
char **_ldap_vals;
char **_ldap_attrs = NULL;
char _ldap_query[AUTH_QUERY_SIZE];
field_t _cfg_ldap_bind_dn,
_cfg_ldap_bind_pw,
_cfg_ldap_base_dn,
_cfg_ldap_port,
_cfg_ldap_scope,
_cfg_ldap_hostname,
_cfg_ldap_objectclass,
_cfg_ldap_field_uid,
_cfg_ldap_field_cid,
_cfg_ldap_field_nid,
_cfg_ldap_field_mail,
_cfg_ldap_field_mailalt,
_cfg_ldap_field_maxmail;
int _cfg_ldap_scope_int;
static void _get_ldap_config()
{
struct list ldapItems;
ReadConfig("LDAP", configFile, &ldapItems);
SetTraceLevel(&ldapItems);
GetConfigValue("BIND_DN", &ldapItems, _cfg_ldap_bind_dn);
if (strlen(_cfg_ldap_bind_dn) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for BIND_DN in config
file");
trace(TRACE_DEBUG, "_get_ldap_config(): bind dn [%s]", _cfg_ldap_bind_dn);
GetConfigValue("BIND_PW", &ldapItems, _cfg_ldap_bind_pw);
if (strlen(_cfg_ldap_bind_pw) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for BIND_PW in config
file");
trace(TRACE_DEBUG, "_get_ldap_config(): bind pw [%s]", _cfg_ldap_bind_pw);
GetConfigValue("BASE_DN", &ldapItems, _cfg_ldap_base_dn);
if (strlen(_cfg_ldap_base_dn) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for BASE_DN in config
file");
trace(TRACE_DEBUG, "_get_ldap_config(): base dn [%s]", _cfg_ldap_base_dn);
GetConfigValue("PORT", &ldapItems, _cfg_ldap_port);
if (strlen(_cfg_ldap_port) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for PORT in config
file");
trace(TRACE_DEBUG, "_get_ldap_config(): port [%s]", _cfg_ldap_port);
GetConfigValue("HOSTNAME", &ldapItems, _cfg_ldap_hostname);
if (strlen(_cfg_ldap_hostname) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for HOSTNAME in config
file");
trace(TRACE_DEBUG, "_get_ldap_config(): hostname [%s]", _cfg_ldap_hostname);
GetConfigValue("OBJECTCLASS", &ldapItems, _cfg_ldap_objectclass);
if (strlen(_cfg_ldap_objectclass) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for OBJECTCLASS in
config file");
trace(TRACE_DEBUG, "_get_ldap_config(): objectclass [%s]",
_cfg_ldap_objectclass);
GetConfigValue("FIELD_UID", &ldapItems, _cfg_ldap_field_uid);
if (strlen(_cfg_ldap_field_uid) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for FIELD_UID in
config file");
trace(TRACE_DEBUG, "_get_ldap_config(): uid field [%s] ",
_cfg_ldap_field_uid);
GetConfigValue("FIELD_CID", &ldapItems, _cfg_ldap_field_cid);
if (strlen(_cfg_ldap_field_cid) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for FIELD_CID in
config file");
trace(TRACE_DEBUG, "_get_ldap_config(): cid field [%s]", _cfg_ldap_field_cid);
GetConfigValue("FIELD_NID", &ldapItems, _cfg_ldap_field_nid);
if (strlen(_cfg_ldap_field_nid) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for FIELD_NID in
config file");
trace(TRACE_DEBUG, "_get_ldap_config(): nid field [%s]", _cfg_ldap_field_nid);
GetConfigValue("FIELD_MAIL", &ldapItems, _cfg_ldap_field_mail);
if (strlen(_cfg_ldap_field_mail) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for FIELD_MAIL in
config file");
trace(TRACE_DEBUG, "_get_ldap_config(): mail field [%s]",
_cfg_ldap_field_mail);
GetConfigValue("FIELD_MAILALT", &ldapItems, _cfg_ldap_field_mailalt);
if (strlen(_cfg_ldap_field_mailalt) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for FIELD_MAILALT in
config file");
trace(TRACE_DEBUG, "_get_ldap_config(): mail alt field [%s]",
_cfg_ldap_field_mailalt);
GetConfigValue("FIELD_QUOTA", &ldapItems, _cfg_ldap_field_maxmail);
if (strlen(_cfg_ldap_field_maxmail) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for FIELD_QUOTA in
config file");
trace(TRACE_DEBUG, "_get_ldap_config(): quota field [%s]",
_cfg_ldap_field_maxmail);
GetConfigValue("SCOPE", &ldapItems, _cfg_ldap_scope);
if (strlen(_cfg_ldap_scope) == 0)
trace(TRACE_DEBUG, "_get_ldap_config(): no value for SCOPE in config
file");
trace(TRACE_DEBUG, "_get_ldap_config(): raw ldap scope is [%s]",
_cfg_ldap_scope);
/* Compare the input string with the possible options,
* making sure not to exceeed the length of the given string */
if( strncasecmp( _cfg_ldap_scope, "one", ( strlen( _cfg_ldap_scope ) < 3 ?
strlen( _cfg_ldap_scope ) : 3 ) ) == 0 )
_cfg_ldap_scope_int = LDAP_SCOPE_ONELEVEL;
else if( strncasecmp( _cfg_ldap_scope, "bas", ( strlen( _cfg_ldap_scope ) < 3
? strlen( _cfg_ldap_scope ) : 3 ) ) == 0 )
_cfg_ldap_scope_int = LDAP_SCOPE_BASE;
else if( strncasecmp( _cfg_ldap_scope, "sub", ( strlen( _cfg_ldap_scope ) < 3
? strlen( _cfg_ldap_scope ) : 3 ) ) == 0 )
_cfg_ldap_scope_int = LDAP_SCOPE_SUBTREE;
else
_cfg_ldap_scope_int = LDAP_SCOPE_SUBTREE;
trace(TRACE_DEBUG, "_get_ldap_config(): integer ldap scope is [%d]",
_cfg_ldap_scope_int);
list_freelist( &ldapItems.start );
}
/*
* auth_connect()
*
* initializes the connection for authentication.
*
* returns 0 on success, -1 on failure
*/
int auth_connect()
{
_get_ldap_config();
trace(TRACE_DEBUG, "auth_connect(): connecting to ldap server on [%s] :
[%s]", _cfg_ldap_hostname, _cfg_ldap_port );
_ldap_conn = ldap_init( _cfg_ldap_hostname, atoi( _cfg_ldap_port ) );
trace(TRACE_DEBUG, "auth_connect(): binding to ldap server as [%s] / [%s]",
_cfg_ldap_bind_dn, _cfg_ldap_bind_pw );
_ldap_err = ldap_bind_s( _ldap_conn, _cfg_ldap_bind_dn, _cfg_ldap_bind_pw,
LDAP_AUTH_SIMPLE );
if( _ldap_err )
{
trace(TRACE_ERROR,"auth_connect(): ldap_bind_s failed: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
trace(TRACE_DEBUG, "auth_connect(): successfully bound to ldap server");
return 0;
}
int auth_disconnect()
{
ldap_unbind( _ldap_conn );
return 0;
}
u64_t auth_user_exists(const char *username)
{
u64_t id;
if (!username)
{
trace(TRACE_ERROR,"auth_user_exists(): got NULL as username");
return 0;
}
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(%s=%s)", _cfg_ldap_field_uid,
username );
trace(TRACE_DEBUG, "auth_user_exists(): searching with query [%s]",
_ldap_query );
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_user_exists(): could not execute query: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
if ( ldap_count_entries( _ldap_conn, _ldap_res ) < 1 )
{
trace (TRACE_DEBUG,"auth_user_exists(): none found");
ldap_msgfree( _ldap_res );
return 0;
}
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_user_exists(): ldap_first_entry failed: %s",
ldap_err2string( _ldap_err ) );
ldap_msgfree( _ldap_res );
return -1;
}
_ldap_vals = ldap_get_values( _ldap_conn, _ldap_msg, _cfg_ldap_field_nid );
id = ( _ldap_vals[0] ) ? strtoull( _ldap_vals[0], NULL, 0 ) : 0;
trace(TRACE_DEBUG, "auth_user_exists(): returned value is [%s]",
_ldap_vals[0] );
ldap_msgfree( _ldap_res );
ldap_value_free( _ldap_vals );
return id;
}
/* return a list of existing users. -2 on mem error, -1 on db-error, 0 on
succes */
int auth_get_known_users(struct list *users)
{
int i, j;
if (!users)
{
trace(TRACE_ERROR,"auth_get_known_users(): got a NULL pointer as
argument");
return -2;
}
list_init(users);
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(objectClass=%s)",
_cfg_ldap_objectclass );
trace(TRACE_DEBUG,"auth_get_known_users(): searching with query
[%s]",_ldap_query);
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace( TRACE_ERROR, "auth_get_known_users(): could not retrieve user
list: %s", ldap_err2string( _ldap_err ) );
return -1;
}
/* find out how many results for our query */
j = ldap_count_entries( _ldap_conn, _ldap_res );
if( j > 0 )
{
/* for the first result we use ldap_first_entry */
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL)
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_get_known_users(): ldap_first_entry failed:
%s", ldap_err2string( _ldap_err ) );
return -1;
}
/* for subsequent results we use ldap_next_entry at the end of the loop */
for ( i = 0; i < j; i++ )
{
/* the LDAPMessage structure has entries for "res" and "msg" so we
use just one of them here */
_ldap_dn = ldap_get_dn( _ldap_conn, _ldap_msg );
if ( _ldap_dn == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_get_known_users(): ldap_get_dn failed:
%s", ldap_err2string( _ldap_err ) );
return -1;
}
trace(TRACE_DEBUG,"auth_get_known_users(): found something at [%s]",
_ldap_dn );
ldap_memfree( _ldap_dn );
_ldap_vals = ldap_get_values( _ldap_conn, _ldap_msg,
_cfg_ldap_field_uid );
if ( _ldap_vals == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_get_known_users(): ldap_get_values failed
for [%s]: %s", _cfg_ldap_field_uid, ldap_err2string( _ldap_err ) );
return -1;
}
if ( !list_nodeadd( users, _ldap_vals[0], strlen( _ldap_vals[0] ) + 1
) )
{
list_freelist( &users->start );
return -2;
}
/* gotta free each result as we're done using it */
ldap_value_free( _ldap_vals );
/* if we're not yet at the last entry, then pull up the next one */
if( i + 1 < j )
{
_ldap_msg = ldap_next_entry( _ldap_conn, _ldap_msg );
if ( _ldap_msg == NULL)
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER,
&_ldap_err);
trace(TRACE_ERROR,"auth_get_known_users(): ldap_next_entry
failed: %s", ldap_err2string( _ldap_err ) );
return -1;
}
}
}
}
else
{
trace(TRACE_ERROR,"auth_get_known_users(): no users found" );
}
/* we already freed that values as we used them in the for loop, just do the
result set now */
ldap_msgfree( _ldap_res );
return 0;
}
/*
* Get the Client ID number
* Return 0 on successful failure
* Return -1 on really big failures
*/
u64_t auth_getclientid(u64_t useridnr)
{
u64_t cid;
if (!useridnr)
{
trace(TRACE_ERROR,"auth_getclientid(): got NULL as useridnr");
return 0;
}
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(%s=%llu)", _cfg_ldap_field_nid,
useridnr );
trace (TRACE_DEBUG,"auth_getclientid(): searching with query
[%s]",_ldap_query);
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_getclientid(): could not execute query: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
if ( ldap_count_entries( _ldap_conn, _ldap_res ) < 1 )
{
trace (TRACE_DEBUG,"auth_getclientid(): no entries found");
return 0;
}
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_getclientid(): ldap_first_entry failed: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
_ldap_dn = ldap_get_dn( _ldap_conn, _ldap_msg );
if ( _ldap_dn == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_getclientid(): ldap_get_dn failed: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
trace(TRACE_DEBUG,"auth_getclientid(): found something at [%s]",
_ldap_dn );
ldap_memfree( _ldap_dn );
_ldap_vals = ldap_get_values( _ldap_conn, _ldap_msg, _cfg_ldap_field_cid );
if( _ldap_vals == NULL )
{
trace (TRACE_DEBUG,"auth_getclientid(): no values found");
cid = 0;
}
else
{
cid = ( _ldap_vals[0] ) ? strtoull( _ldap_vals[0], NULL, 0 ) : 0;
}
ldap_msgfree( _ldap_res );
ldap_value_free( _ldap_vals );
return cid;
}
u64_t auth_getmaxmailsize(u64_t useridnr)
{
u64_t maxmailsize;
if (!useridnr)
{
trace(TRACE_ERROR,"auth_getmaxmailsize(): got NULL as useridnr");
return 0;
}
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(%s=%llu)", _cfg_ldap_field_nid,
useridnr );
trace (TRACE_DEBUG,"auth_getmaxmailsize(): searching with query
[%s]",_ldap_query);
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_getmaxmailsize(): could not execute query: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
if ( ldap_count_entries( _ldap_conn, _ldap_res ) < 1 )
{
trace (TRACE_DEBUG,"auth_getmaxmailsize(): no entries found");
return 0;
}
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_getmaxmailsize(): ldap_first_entry failed: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
_ldap_dn = ldap_get_dn( _ldap_conn, _ldap_msg );
if ( _ldap_dn == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_getmaxmailsize(): ldap_get_dn failed:
%s", ldap_err2string( _ldap_err ) );
return -1;
}
trace(TRACE_DEBUG,"auth_getmaxmailsize(): found something at [%s]",
_ldap_dn );
ldap_memfree( _ldap_dn );
_ldap_vals = ldap_get_values( _ldap_conn, _ldap_msg, _cfg_ldap_field_maxmail
);
if( _ldap_vals == NULL )
{
trace (TRACE_DEBUG,"auth_getmaxmailsize(): no values found");
maxmailsize = 0;
}
else
{
maxmailsize = ( _ldap_vals[0] ) ? strtoull( _ldap_vals[0], 0, 10 ) : -1;
}
ldap_msgfree( _ldap_res );
ldap_value_free( _ldap_vals );
return maxmailsize;
}
/*
* auth_getencryption()
*
* returns a string describing the encryption used for the passwd storage
* for this user.
* The string is valid until the next function call; in absence of any
* encryption the string will be empty (not null).
*
* If the specified user does not exist an empty string will be returned.
*/
char *auth_getencryption(u64_t useridnr)
{
/* ldap does not support fancy passwords */
return 0;
}
/* recursive function, should be called with checks == -1 from main routine */
int auth_check_user (const char *address, struct list *userids, int checks)
{
int occurences=0, r;
int i, j;
trace(TRACE_DEBUG,"auth_check_user(): checking for user [%s]",address);
if (checks > MAX_CHECKS_DEPTH)
{
trace(TRACE_ERROR, "auth_check_user(): maximum checking depth reached,
there probably is a loop in your alias table");
return -1;
}
snprintf ( _ldap_query, AUTH_QUERY_SIZE, "(|(%s=%s)(%s=%s))",
_cfg_ldap_field_mail, address, _cfg_ldap_field_mailalt, address );
trace(TRACE_DEBUG,"auth_check_user(): searching with query [%s]",_ldap_query);
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_check_user(): could not execute query [%s]",
ldap_err2string( _ldap_err ) );
return -1;
}
/* we're just using a little counter variable, since we'll use it in the for
loop later */
j = ldap_count_entries( _ldap_conn, _ldap_res );
if ( j < 1 )
{
if ( checks > 0 )
{
/* found the last one, this is the deliver to
* but checks needs to be bigger then 0 because
* else it could be the first query failure */
list_nodeadd( userids, address, strlen( address ) + 1 );
trace (TRACE_DEBUG,"auth_check_user(): adding [%s] to deliver_to
address",address);
return 1;
}
else
{
trace (TRACE_DEBUG,"auth_check_user(): user [%s] not in aliases
table",address);
return 0;
}
}
trace (TRACE_DEBUG,"auth_check_user(): into checking loop");
if ( ldap_count_entries( _ldap_conn, _ldap_res ) < 1 )
{
trace (TRACE_DEBUG,"auth_check_user(): none found");
return 0;
}
/* do the first entry here */
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_check_user(): ldap_first_entry failed: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
/* we'll get the next entry at the _end_ of the loop! */
for ( i = 0; i < j; i++ )
{
_ldap_vals = ldap_get_values( _ldap_conn, _ldap_msg, _cfg_ldap_field_cid );
// FIXME: what field is this?
/* do a recursive search for deliver_to */
trace (TRACE_DEBUG,"auth_check_user(): checking user [%s] to [%s]",address,
_ldap_vals[0]);
r = auth_check_user (_ldap_vals[0], userids, (checks < 0) ? 1 : checks+1);
/* remember, this is freed as soon as it's no longer needed */
ldap_value_free( _ldap_vals );
if (r < 0)
{
/* loop detected */
if (checks > 0)
return -1; /* still in recursive call */
if (userids->start)
{
list_freelist(&userids->start);
userids->total_nodes = 0;
}
return 0; /* report to calling routine: no results */
}
occurences += r;
/* do the next entry here */
_ldap_msg = ldap_next_entry( _ldap_conn, _ldap_msg );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_check_user(): ldap_next_entry failed: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
}
trace(TRACE_DEBUG,"auth_check_user(): executing query, checks [%d]", checks);
/* trace(TRACE_INFO,"auth_check_user(): user [%s] has [%d]
entries",address,occurences); */
ldap_msgfree( _ldap_res );
return occurences;
}
/*
* auth_check_user_ext()
*
* As auth_check_user() but adds the numeric ID of the user found
* to userids or the forward to the fwds.
*
* returns the number of occurences.
*/
int auth_check_user_ext(const char *address, struct list *userids, struct list
*fwds, int checks)
{
int i, j;
int occurences=0;
u64_t id;
char *endptr = NULL;
trace(TRACE_DEBUG,"auth_check_user_ext(): checking user [%s] in alias
table",address);
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(|(%s=%s)(%s=%s)",
_cfg_ldap_field_mail, address, _cfg_ldap_field_mailalt, address );
trace(TRACE_DEBUG,"auth_check_user_ext(): searching with query
[%s]",_ldap_query);
trace(TRACE_DEBUG,"auth_check_user_ext(): executing query, checks [%d]",
checks);
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_check_user_ext(): could not execute query: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
/* we're just using a little counter variable, since we'll use it in the for
loop later */
j = ldap_count_entries( _ldap_conn, _ldap_res );
if ( i < 1 )
{
if (checks>0)
{
/* found the last one, this is the deliver to
* but checks needs to be bigger then 0 because
* else it could be the first query failure */
id = strtoull(address, &endptr, 10);
if (*endptr == 0)
list_nodeadd(userids, &id, sizeof(id)); /* numeric deliver-to -->
this is a userid */
else
list_nodeadd(fwds, address, strlen(address)+1);
trace (TRACE_DEBUG,"auth_check_user_ext(): adding [%s] to deliver_to
address", address);
return 1;
}
else
{
trace (TRACE_DEBUG,"auth_check_user_ext(): user [%s] not in aliases
table", address);
return 0;
}
}
trace (TRACE_DEBUG,"auth_check_user_ext(): into checking loop");
if ( ldap_count_entries( _ldap_conn, _ldap_res ) < 1 )
{
trace (TRACE_DEBUG,"auth_check_user_ext(): none found");
return 0;
}
/* do the first entry here */
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_check_user_ext(): ldap_first_entry failed: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
/* we'll get the next entry at the _end_ of the loop! */
for ( i = 0; i < j; i++ )
{
_ldap_vals = ldap_get_values( _ldap_conn, _ldap_msg, _cfg_ldap_field_cid
); // FIXME: what field is this?
/* do a recursive search for deliver_to */
trace (TRACE_DEBUG,"auth_check_user_ext(): checking user %s to
%s",address, _ldap_vals[0]);
occurences += auth_check_user_ext(_ldap_vals[0], userids, fwds, 1);
ldap_value_free( _ldap_vals );
/* do the next entry here */
_ldap_msg = ldap_next_entry( _ldap_conn, _ldap_msg );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_check_user_ext(): ldap_next_entry failed:
%s", ldap_err2string( _ldap_err ) );
return -1;
}
}
trace(TRACE_DEBUG,"auth_check_user_ext(): executing query, checks [%d]",
checks);
/* trace(TRACE_INFO,"auth_check_user(): user [%s] has [%d]
entries",address,occurences); */
ldap_msgfree( _ldap_res );
return occurences;
}
/*
* auth_adduser()
*
* adds a new user to the database
* and adds a INBOX
* returns a useridnr on succes, -1 on failure
*/
u64_t auth_adduser (char *username, char *password, char *enctype, char
*clientid, char *maxmail)
{
int i, j, ret;
int NUM_MODS = 8;
char *kaboom = "123";
char *cn_values[] = { username, NULL };
char *sn_values[] = { username, NULL };
char *obj_values[] = { "top", "person", _cfg_ldap_objectclass, NULL };
char *uid_values[] = { username, NULL };
char *cid_values[] = { clientid, NULL };
char *nid_values[] = { kaboom, NULL };
char *max_values[] = { maxmail, NULL };
/* Make the malloc for all of the pieces we're about to to sprintf into it */
_ldap_dn = (char *)my_malloc( strlen( "cn=," ) + strlen( username ) + strlen(
_cfg_ldap_base_dn ) + 1 );
sprintf( _ldap_dn, "cn=%s,%s", username, _cfg_ldap_base_dn );
trace( TRACE_DEBUG, "Adding user with DN of [%s]", _ldap_dn );
/* Construct the array of LDAPMod structures representing the attributes
* of the new entry. */
_ldap_mod = ( LDAPMod ** ) my_malloc( ( NUM_MODS + 1 ) * sizeof( LDAPMod * )
);
if ( _ldap_mod == NULL )
{
trace( TRACE_ERROR, "Cannot allocate memory for mods array" );
return -1;
}
for ( i = 0; i < NUM_MODS; i++ )
{
if ( ( _ldap_mod[ i ] = ( LDAPMod * ) my_malloc( sizeof( LDAPMod ) ) ) ==
NULL )
{
trace( TRACE_ERROR, "Cannot allocate memory for mods element %d", i );
/* Free everything that did get allocated, which is (i-1) elements */
for( j = 0; j < (i-1); j++ )
my_free( _ldap_mod[j] );
my_free( _ldap_mod );
ldap_msgfree( _ldap_res );
return -1;
}
}
i=0;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, "objectclass", obj_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = "objectclass";
_ldap_mod[i]->mod_values = obj_values;
i++;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, "cn", cn_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = "cn";
_ldap_mod[i]->mod_values = cn_values;
i++;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, "sn", cn_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = "sn";
_ldap_mod[i]->mod_values = cn_values;
i++;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, "mail", sn_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = "mail";
_ldap_mod[i]->mod_values = sn_values;
i++;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, _cfg_ldap_field_uid, uid_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = _cfg_ldap_field_uid;
_ldap_mod[i]->mod_values = uid_values;
i++;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, _cfg_ldap_field_cid, cid_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = _cfg_ldap_field_cid;
_ldap_mod[i]->mod_values = cid_values;
i++;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, _cfg_ldap_field_maxmail, max_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = _cfg_ldap_field_maxmail;
_ldap_mod[i]->mod_values = max_values;
/* FIXME: need to quackulate a free numeric user id number */
i++;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, _cfg_ldap_field_nid, nid_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = _cfg_ldap_field_nid;
_ldap_mod[i]->mod_values = nid_values;
i++;
trace( TRACE_DEBUG, "Placing a NULL to terminate the LDAPMod array at element
%d", i );
_ldap_mod[i] = NULL;
trace( TRACE_DEBUG, "auth_adduser(): calling ldap_add_s( _ldap_conn,
_ldap_dn, _ldap_mod )" );
_ldap_err = ldap_add_s( _ldap_conn, _ldap_dn, _ldap_mod );
/* make sure to free this stuff even if we do bomb out! */
for( i = 0; i < NUM_MODS; i++ )
my_free( _ldap_mod[i] );
my_free( _ldap_mod );
ldap_memfree( _ldap_dn );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_adduser(): could not add user: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
return strtoull( nid_values[0], 0, 0 );
}
int auth_delete_user(const char *username)
{
/* look up who's got that username, get their dn, and delete it! */
if ( !username )
{
trace(TRACE_ERROR,"auth_get_userid(): got NULL as useridnr");
return 0;
}
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(%s=%s)", _cfg_ldap_field_uid,
username );
trace(TRACE_DEBUG,"auth_delete_user(): searching with query [%s]",
_ldap_query );
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_delete_user(): could not execute query: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
if ( ldap_count_entries( _ldap_conn, _ldap_res ) < 1 )
{
trace (TRACE_DEBUG,"auth_delete_user(): no entries found");
ldap_msgfree( _ldap_res );
return 0;
}
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_delete_user(): ldap_first_entry failed: %s",
ldap_err2string( _ldap_err ) );
ldap_msgfree( _ldap_res );
return -1;
}
_ldap_dn = ldap_get_dn( _ldap_conn, _ldap_msg );
if ( _ldap_dn )
{
trace(TRACE_DEBUG,"auth_delete_user(): deleting user at dn [%s]",
_ldap_dn );
_ldap_err = ldap_delete_s( _ldap_conn, _ldap_dn );
if( _ldap_err )
{
trace(TRACE_ERROR, "auth_delete_user(): could not delete dn: %s",
ldap_err2string( _ldap_err ) );
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
return -1;
}
}
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
return 0;
}
int auth_change_username(u64_t useridnr, const char *newname)
{
int i, j, NUM_MODS = 2;
char *new_values[] = { newname, NULL };
if ( !useridnr )
{
trace(TRACE_ERROR,"auth_change_username(): got NULL as useridnr");
return 0;
}
if ( !newname )
{
trace(TRACE_ERROR,"auth_change_username(): got NULL as newname");
return 0;
}
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(%s=%llu)", _cfg_ldap_field_nid,
useridnr );
trace(TRACE_DEBUG,"auth_change_username(): searching with query [%s]",
_ldap_query );
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_change_username(): could not execute query: %s",
ldap_err2string( _ldap_err ) );
return 0;
}
if ( ldap_count_entries( _ldap_conn, _ldap_res ) < 1 )
{
trace (TRACE_DEBUG,"auth_change_username(): no entries found");
ldap_msgfree( _ldap_res );
return 0;
}
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_change_username(): ldap_first_entry failed: %s",
ldap_err2string( _ldap_err ) );
ldap_msgfree( _ldap_res );
return 0;
}
_ldap_dn = ldap_get_dn( _ldap_conn, _ldap_msg );
if ( _ldap_dn == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_change_username(): ldap_get_dn failed: %s",
ldap_err2string( _ldap_err ) );
ldap_msgfree( _ldap_res );
return -1;
}
trace(TRACE_DEBUG,"auth_change_username(): found something at [%s]", _ldap_dn
);
/* Construct the array of LDAPMod structures representing the attributes
* of the new entry. */
_ldap_mod = ( LDAPMod ** ) my_malloc( ( NUM_MODS + 1 ) * sizeof( LDAPMod * )
);
if ( _ldap_mod == NULL )
{
trace( TRACE_ERROR, "Cannot allocate memory for mods array" );
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
return -1;
}
for ( i = 0; i < NUM_MODS; i++ )
{
if ( ( _ldap_mod[ i ] = ( LDAPMod * ) my_malloc( sizeof( LDAPMod ) ) ) ==
NULL )
{
trace( TRACE_ERROR, "Cannot allocate memory for mods element %d", i );
/* Free everything that did get allocated, which is (i-1) elements */
for( j = 0; j < (i-1); j++ )
my_free( _ldap_mod[j] );
my_free( _ldap_mod );
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
return -1;
}
}
i=0;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, _cfg_ldap_field_uid, new_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_REPLACE;
_ldap_mod[i]->mod_type = _cfg_ldap_field_uid;
_ldap_mod[i]->mod_values = new_values;
i++;
trace( TRACE_DEBUG, "Placing a NULL to terminate the LDAPMod array at element
%d", i );
_ldap_mod[i] = NULL;
trace( TRACE_DEBUG, "auth_change_username(): calling ldap_modify_s(
_ldap_conn, _ldap_dn, _ldap_mod )" );
_ldap_err = ldap_modify_s( _ldap_conn, _ldap_dn, _ldap_mod );
/* make sure to free this stuff even if we do bomb out! */
for( i = 0; i < NUM_MODS; i++ )
my_free( _ldap_mod[i] );
my_free( _ldap_mod );
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_change_username(): could not change username:
%s", ldap_err2string( _ldap_err ) );
return -1;
}
return 1;
}
int auth_change_password(u64_t useridnr, const char *newpass, const char
*enctype)
{
return -1;
}
int auth_change_clientid(u64_t useridnr, u64_t newcid)
{
int i, j, NUM_MODS = 2;
char *newcid_str[100];
char *new_values[] = { newcid_str, NULL };
if ( !useridnr )
{
trace(TRACE_ERROR,"auth_change_clientid(): got NULL as useridnr");
return 0;
}
if ( !newcid )
{
trace(TRACE_ERROR,"auth_change_clientid(): got NULL as newcid");
return 0;
}
snprintf( new_values[0], 100, "%llu", newcid ); // Yeah, something like
this...
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(%s=%llu)", _cfg_ldap_field_nid,
useridnr );
trace(TRACE_DEBUG,"auth_change_clientid(): searching with query [%s]",
_ldap_query );
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_change_clientid(): could not execute query: %s",
ldap_err2string( _ldap_err ) );
return 0;
}
if ( ldap_count_entries( _ldap_conn, _ldap_res ) < 1 )
{
trace (TRACE_DEBUG,"auth_change_clientid(): no entries found");
ldap_msgfree( _ldap_res );
return 0;
}
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_change_clientid(): ldap_first_entry failed: %s",
ldap_err2string( _ldap_err ) );
ldap_msgfree( _ldap_res );
return 0;
}
_ldap_dn = ldap_get_dn( _ldap_conn, _ldap_msg );
if ( _ldap_dn == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_change_clientid(): ldap_get_dn failed: %s",
ldap_err2string( _ldap_err ) );
ldap_msgfree( _ldap_res );
return -1;
}
trace(TRACE_DEBUG,"auth_change_clientid(): found something at [%s]", _ldap_dn
);
/* Construct the array of LDAPMod structures representing the attributes
* of the new entry. */
_ldap_mod = ( LDAPMod ** ) my_malloc( ( NUM_MODS + 1 ) * sizeof( LDAPMod * )
);
if ( _ldap_mod == NULL )
{
trace( TRACE_ERROR, "Cannot allocate memory for mods array" );
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
return -1;
}
for ( i = 0; i < NUM_MODS; i++ )
{
if ( ( _ldap_mod[ i ] = ( LDAPMod * ) my_malloc( sizeof( LDAPMod ) ) ) ==
NULL )
{
trace( TRACE_ERROR, "Cannot allocate memory for mods element %d", i );
/* Free everything that did get allocated, which is (i-1) elements */
for( j = 0; j < (i-1); j++ )
my_free( _ldap_mod[j] );
my_free( _ldap_mod );
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
return -1;
}
}
i=0;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, _cfg_ldap_field_cid, new_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_REPLACE;
_ldap_mod[i]->mod_type = _cfg_ldap_field_cid;
_ldap_mod[i]->mod_values = new_values;
i++;
trace( TRACE_DEBUG, "Placing a NULL to terminate the LDAPMod array at element
%d", i );
_ldap_mod[i] = NULL;
trace( TRACE_DEBUG, "auth_change_clientid(): calling ldap_modify_s(
_ldap_conn, _ldap_dn, _ldap_mod )" );
_ldap_err = ldap_modify_s( _ldap_conn, _ldap_dn, _ldap_mod );
/* make sure to free this stuff even if we do bomb out! */
for( i = 0; i < NUM_MODS; i++ )
my_free( _ldap_mod[i] );
my_free( _ldap_mod );
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_change_clientid(): could not change clientid:
%s", ldap_err2string( _ldap_err ) );
return -1;
}
return 1;
}
int auth_change_mailboxsize(u64_t useridnr, u64_t newsize)
{
int i, j, NUM_MODS = 2;
char *newsize_str[100];
char *new_values[] = { newsize_str, NULL };
if ( !useridnr )
{
trace(TRACE_ERROR,"auth_change_mailboxsize(): got NULL as useridnr");
return 0;
}
if ( !newsize )
{
trace(TRACE_ERROR,"auth_change_mailboxsize(): got NULL as newsize");
return 0;
}
snprintf( new_values[0], 100, "%llu", newsize );
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(%s=%llu)", _cfg_ldap_field_nid,
useridnr );
trace(TRACE_DEBUG,"auth_change_mailboxsize(): searching with query [%s]",
_ldap_query );
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_change_mailboxsize(): could not execute query:
%s", ldap_err2string( _ldap_err ) );
return 0;
}
if ( ldap_count_entries( _ldap_conn, _ldap_res ) < 1 )
{
trace (TRACE_DEBUG,"auth_change_mailboxsize(): no entries found");
ldap_msgfree( _ldap_res );
return 0;
}
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_change_mailboxsize(): ldap_first_entry failed:
%s", ldap_err2string( _ldap_err ) );
ldap_msgfree( _ldap_res );
return 0;
}
_ldap_dn = ldap_get_dn( _ldap_conn, _ldap_msg );
if ( _ldap_dn == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_change_mailboxsize(): ldap_get_dn failed: %s",
ldap_err2string( _ldap_err ) );
ldap_msgfree( _ldap_res );
return -1;
}
trace(TRACE_DEBUG,"auth_change_mailboxsize(): found something at [%s]",
_ldap_dn );
/* Construct the array of LDAPMod structures representing the attributes
* of the new entry. */
_ldap_mod = ( LDAPMod ** ) my_malloc( ( NUM_MODS + 1 ) * sizeof( LDAPMod * )
);
if ( _ldap_mod == NULL )
{
trace( TRACE_ERROR, "Cannot allocate memory for mods array" );
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
return -1;
}
for ( i = 0; i < NUM_MODS; i++ )
{
if ( ( _ldap_mod[ i ] = ( LDAPMod * ) my_malloc( sizeof( LDAPMod ) ) ) ==
NULL )
{
trace( TRACE_ERROR, "Cannot allocate memory for mods element %d", i );
/* Free everything that did get allocated, which is (i-1) elements */
for( j = 0; j < (i-1); j++ )
my_free( _ldap_mod[j] );
my_free( _ldap_mod );
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
return -1;
}
}
i=0;
trace( TRACE_DEBUG, "Starting to define LDAPMod element %d type %s value %s",
i, _cfg_ldap_field_maxmail, new_values[0] );
_ldap_mod[i]->mod_op = LDAP_MOD_REPLACE;
_ldap_mod[i]->mod_type = _cfg_ldap_field_maxmail;
_ldap_mod[i]->mod_values = new_values;
i++;
trace( TRACE_DEBUG, "Placing a NULL to terminate the LDAPMod array at element
%d", i );
_ldap_mod[i] = NULL;
trace( TRACE_DEBUG, "auth_change_mailboxsize(): calling ldap_modify_s(
_ldap_conn, _ldap_dn, _ldap_mod )" );
_ldap_err = ldap_modify_s( _ldap_conn, _ldap_dn, _ldap_mod );
/* make sure to free this stuff even if we do bomb out! */
for( i = 0; i < NUM_MODS; i++ )
my_free( _ldap_mod[i] );
my_free( _ldap_mod );
ldap_memfree( _ldap_dn );
ldap_msgfree( _ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_change_mailboxsize(): could not change
mailboxsize: %s", ldap_err2string( _ldap_err ) );
return -1;
}
return 1;
}
/*
* auth_validate()
*
* tries to validate user 'user'
*
* returns useridnr on OK, 0 on validation failed, -1 on error
*/
u64_t auth_validate (char *user, char *password)
{
u64_t id;
int is_validated = 0;
char timestr[30];
time_t td;
struct tm tm;
time(&td); /* get time */
tm = *localtime(&td); /* get components */
strftime(timestr, sizeof(timestr), "%G-%m-%d %H:%M:%S", &tm);
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(%s=%s)", _cfg_ldap_field_uid, user
);
trace (TRACE_DEBUG,"auth_validate(): searching with query [%s]",_ldap_query);
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_validate(): could not search for user: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
if ( ldap_count_entries( _ldap_conn, _ldap_res ) > 0 )
{
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if( _ldap_msg == NULL )
{
trace(TRACE_ERROR, "auth_validate(): could not get first entry: %s",
ldap_err2string( _ldap_err ) );
return -1;
}
}
else
{
/* user does not exist */
trace (TRACE_DEBUG,"auth_validate(): user [%s] not found",user);
return 0;
}
_ldap_dn = ldap_get_dn( _ldap_conn, _ldap_msg );
/* now, try to rebind as the given DN using the supplied password */
trace (TRACE_ERROR,"auth_validate(): rebinding as [%s] to validate
password",_ldap_dn);
_ldap_err = ldap_bind_s( _ldap_conn, _ldap_dn, password, LDAP_AUTH_SIMPLE );
ldap_memfree( _ldap_dn );
// FIXME: do we need to bind back to the dbmail "superuser" again?
if( _ldap_err )
{
trace(TRACE_ERROR,"auth_validate(): ldap_bind_s failed: %s",
ldap_err2string( _ldap_err ) );
return 0;
}
else
{
_ldap_vals = ldap_get_values( _ldap_conn, _ldap_msg, _cfg_ldap_field_nid
);
trace (TRACE_ERROR,"auth_validate(): returning numeric id
[%s]",_ldap_vals[0]);
id = (_ldap_vals[0]) ? strtoull(_ldap_vals[0], NULL, 10) : 0;
/* FIXME: implement this in LDAP... log login in the dbase
snprintf(__auth_query_data, AUTH_QUERY_SIZE, "UPDATE users SET last_login
= '%s' "
"WHERE user_idnr = %llu", timestr, id);
if (__auth_query(__auth_query_data)==-1)
trace(TRACE_ERROR, "auth_validate(): could not update user login time");
*/
}
ldap_msgfree( _ldap_res );
ldap_value_free( _ldap_vals );
return id;
}
u64_t auth_md5_validate (char *username,unsigned char *md5_apop_he, char
*apop_stamp)
{
/* returns useridnr on OK, 0 on validation failed, -1 on error */
return 0;
}
/* Given a useridnr, find the account/login name
* return 0 if not found, NULL on error
*/
char *auth_get_userid (u64_t *useridnr)
{
char *returnid = NULL;
if ( !useridnr )
{
trace(TRACE_ERROR,"auth_get_userid(): got NULL as useridnr");
return 0;
}
snprintf( _ldap_query, AUTH_QUERY_SIZE, "(%s=%llu)", _cfg_ldap_field_nid,
*useridnr );
trace(TRACE_DEBUG,"auth_get_userid(): searching with query [%s]", _ldap_query
);
_ldap_err = ldap_search_s( _ldap_conn, _cfg_ldap_base_dn,
_cfg_ldap_scope_int, _ldap_query, _ldap_attrs, _ldap_attrsonly, &_ldap_res );
if ( _ldap_err )
{
trace(TRACE_ERROR, "auth_get_userid(): could not execute query: %s",
ldap_err2string( _ldap_err ) );
return NULL;
}
if ( ldap_count_entries( _ldap_conn, _ldap_res ) < 1 )
{
trace (TRACE_DEBUG,"auth_get_userid(): no entries found");
return 0;
}
_ldap_msg = ldap_first_entry( _ldap_conn, _ldap_res );
if ( _ldap_msg == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_get_userid(): ldap_first_entry failed: %s",
ldap_err2string( _ldap_err ) );
return NULL;
}
_ldap_dn = ldap_get_dn( _ldap_conn, _ldap_msg );
if ( _ldap_dn == NULL )
{
ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
trace(TRACE_ERROR,"auth_get_userid(): ldap_get_dn failed: %s",
ldap_err2string( _ldap_err ) );
return NULL;
}
trace(TRACE_DEBUG,"auth_get_userid(): found something at [%s]", _ldap_dn );
ldap_memfree( _ldap_dn );
_ldap_vals = ldap_get_values( _ldap_conn, _ldap_msg, _cfg_ldap_field_uid );
if ( _ldap_vals )
{
if ( !( returnid = (char *)my_malloc( strlen( _ldap_vals[0] ) + 1 ) ) )
{
trace( TRACE_ERROR, "auth_get_userid(): out of memory" );
return NULL;
}
/* this is safe because we calculated the size three lines ago */
strcpy ( returnid, _ldap_vals[0] );
}
ldap_value_free( _ldap_vals );
ldap_msgfree( _ldap_res );
return returnid;
}