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; }