* along with srvx; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
+ *
+ * INSTRUCTIONS:
+ * * Setup an ldap server. Add inetOrgAnon to the schema (it is in tools/ldap)
+ * * Make sure ldap is enabled at compile time (debian needs libldap2-dev package)
+ * * Enable ldap in x3.conf and set everything
+ * * Initial import: you can use the secret authserv search action add2ldap
+ * to get your users into ldap. /msg authserv search add2ldap account *
*
* TODO:
* * get queries working in static existance, so i understand how it works
#include "config.h"
#ifdef WITH_LDAP
+#define LDAP_DEPRECATED 1
+
#include <stdio.h>
#include <stdlib.h>
#include <ldap.h>
+#include "base64.h"
#include "conf.h"
#include "global.h"
#include "log.h"
}
-unsigned int ldap_check_auth( char *account, char *pass)
+unsigned int ldap_check_auth( const char *account, const char *pass)
{
char buff[MAXLEN];
}
-int ldap_search_user(char *account, LDAPMessage **entry)
+int ldap_search_user(const char *account, LDAPMessage **entry)
{
char filter[MAXLEN+1];
* 0 or 2+ entries are matched, or the proper ldap error
* code for other errors.
*/
-int ldap_get_user_info(char *account, char **email)
+int ldap_get_user_info(const char *account, char **email)
{
int rc;
- char **value;
+ struct berval **value;
LDAPMessage *entry, *res;
if(email)
*email = NULL;
if( (rc = ldap_search_user(account, &res)) == LDAP_SUCCESS) {
entry = ldap_first_entry(ld, res);
- value = ldap_get_values(ld, entry, nickserv_conf.ldap_field_email);
+ value = ldap_get_values_len(ld, entry, nickserv_conf.ldap_field_email);
if(!value) {
return(LDAP_OTHER);
}
if(email)
- *email = strdup(value[0]);
- log_module(MAIN_LOG, LOG_DEBUG, "%s: %s\n", nickserv_conf.ldap_field_email, value[0]);
+ *email = strdup(value[0]->bv_val);
+ log_module(MAIN_LOG, LOG_DEBUG, "%s: %s\n", nickserv_conf.ldap_field_email, value[0]->bv_val);
+ ldap_value_free_len(value);
/*
value = ldap_get_values(ld, entry, "description");
log_module(MAIN_LOG, LOG_DEBUG, "Description: %s\n", value[0]);
return(buf);
}
-
-/* from php5 sources */
-static char base64_table[] =
- { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
- };
-static char base64_pad = '=';
-
-char *base64_encode(const unsigned char *str, int length, int *ret_length)
-{
- const unsigned char *current = str;
- char *p;
- char *result;
-
- if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
- if (ret_length != NULL) {
- *ret_length = 0;
- }
- return NULL;
- }
-
- result = (char *)calloc((((length + 2) / 3) * 4)+1, sizeof(char));
- p = result;
-
- while (length > 2) { /* keep going until we have less than 24 bits */
- *p++ = base64_table[current[0] >> 2];
- *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
- *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
- *p++ = base64_table[current[2] & 0x3f];
-
- current += 3;
- length -= 3; /* we just handle 3 octets of data */
- }
-
- /* now deal with the tail end of things */
- if (length != 0) {
- *p++ = base64_table[current[0] >> 2];
- if (length > 1) {
- *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
- *p++ = base64_table[(current[1] & 0x0f) << 2];
- *p++ = base64_pad;
- } else {
- *p++ = base64_table[(current[0] & 0x03) << 4];
- *p++ = base64_pad;
- *p++ = base64_pad;
- }
- }
- if (ret_length != NULL) {
- *ret_length = (int)(p - result);
- }
- *p = '\0';
- return result;
-}
-
-
char **make_object_vals()
{
unsigned int y;
if(object_vals)
free(object_vals);
- object_vals = malloc(sizeof( *object_vals ) * nickserv_conf.ldap_object_classes->used);
+ object_vals = malloc(sizeof( *object_vals ) * (nickserv_conf.ldap_object_classes->used+1));
for(y = 0; y < nickserv_conf.ldap_object_classes->used; y++) {
object_vals[y] = nickserv_conf.ldap_object_classes->list[y];
}
object_vals[y] = NULL;
return object_vals;
+ /* NOTE: The return value of this is only good until the next call to it. */
}
char *make_password(const char *crypted)
char *passbuf;
packed = pack(crypted, &len);
- base64pass = base64_encode(packed, len, NULL);
+ base64_encode_alloc((char *)packed, len, &base64pass);
passbuf = malloc(strlen(base64pass) + 1 + 5);
strcpy(passbuf, "{MD5}");
strcat(passbuf, base64pass);
static char *account_vals[] = { NULL, NULL };
static char *password_vals[] = { NULL, NULL };
static char *email_vals[] = { NULL, NULL };
- int num_mods = 3;
+ int num_mods = 2;
int i;
+ int mod = 0;
/* TODO: take this from nickserv_conf.ldap_add_objects */
LDAPMod **mods;
static char **object_vals;
+
+ account_vals[0] = NULL;
+ account_vals[1] = NULL;
+ password_vals[0] = NULL;
+ password_vals[1] = NULL;
+ email_vals[0] = NULL;
+ email_vals[1] = NULL;
object_vals = make_object_vals();
account_vals[0] = (char *) account;
- password_vals[0] = (char *) password;
+ if (password != NULL) {
+ password_vals[0] = (char *) password;
+ num_mods++;
+ }
email_vals[0] = (char *) email;
if(!(nickserv_conf.ldap_field_account && *nickserv_conf.ldap_field_account))
memset(mods[i], 0, sizeof(LDAPMod));
}
- mods[0]->mod_op = LDAP_MOD_ADD;
- mods[0]->mod_type = strdup("objectclass");
- mods[0]->mod_values = object_vals;
+ mods[mod]->mod_op = LDAP_MOD_ADD;
+ mods[mod]->mod_type = strdup("objectclass");
+ mods[mod]->mod_values = object_vals;
+ mod++;
- mods[1]->mod_op = LDAP_MOD_ADD;
- mods[1]->mod_type = strdup(nickserv_conf.ldap_field_account);
- mods[1]->mod_values = account_vals;
+ mods[mod]->mod_op = LDAP_MOD_ADD;
+ mods[mod]->mod_type = strdup(nickserv_conf.ldap_field_account);
+ mods[mod]->mod_values = account_vals;
+ mod++;
- mods[2]->mod_op = LDAP_MOD_ADD;
- mods[2]->mod_type = strdup(nickserv_conf.ldap_field_password);
- mods[2]->mod_values = password_vals;
+ if (password != NULL) {
+ mods[mod]->mod_op = LDAP_MOD_ADD;
+ mods[mod]->mod_type = strdup(nickserv_conf.ldap_field_password);
+ mods[mod]->mod_values = password_vals;
+ mod++;
+ }
if(nickserv_conf.ldap_field_email && *nickserv_conf.ldap_field_email && email && *email) {
- mods[3]->mod_op = LDAP_MOD_ADD;
- mods[3]->mod_type = strdup(nickserv_conf.ldap_field_email);
- mods[3]->mod_values = email_vals;
- mods[4] = NULL;
+ mods[mod]->mod_op = LDAP_MOD_ADD;
+ mods[mod]->mod_type = strdup(nickserv_conf.ldap_field_email);
+ mods[mod]->mod_values = email_vals;
+ mod++;
}
- else
- mods[3] = NULL;
+ mods[mod] = NULL;
*num_mods_ret = num_mods;
return mods;
}
LDAPMod **mods;
int rc, i;
int num_mods;
- char *passbuf;
+ char *passbuf = NULL;
if(!admin_bind && LDAP_SUCCESS != ( rc = ldap_do_admin_bind())) {
log_module(MAIN_LOG, LOG_ERROR, "failed to bind as admin");
return rc;
}
-
- passbuf = make_password(crypted);
+
+ if (crypted != NULL)
+ passbuf = make_password(crypted);
snprintf(newdn, MAXLEN-1, nickserv_conf.ldap_dn_fmt, account);
- mods = make_mods_add(account, passbuf, email, &num_mods);
+ mods = make_mods_add(account, (crypted != NULL ? passbuf : crypted), email, &num_mods);
if(!mods) {
log_module(MAIN_LOG, LOG_ERROR, "Error building mods for ldap_add");
return LDAP_OTHER;
free(mods[i]);
}
free(mods);
- free(passbuf);
+ if (crypted != NULL)
+ free(passbuf);
return rc;
}
*
* A level of <0 will be treated as 0
*/
-int ldap_do_oslevel(const char *account, int level)
+int ldap_do_oslevel(const char *account, int level, int oldlevel)
{
LDAPMod **mods;
static char *oslevel_vals[] = { NULL, NULL };
level = 0;
}
- snprintf(temp, MAXLEN-1, "%d", level);
+ snprintf(temp, MAXLEN-1, "%d", (level ? level : oldlevel));
oslevel_vals[0] = (char *) temp;
if(!(nickserv_conf.ldap_field_oslevel && *nickserv_conf.ldap_field_oslevel))
mods[0] = (LDAPMod *) malloc(sizeof(LDAPMod));
memset(mods[0], 0, sizeof(LDAPMod));
- mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_op = (level ? LDAP_MOD_REPLACE : LDAP_MOD_DELETE);
mods[0]->mod_type = strdup(nickserv_conf.ldap_field_oslevel);
mods[0]->mod_values = oslevel_vals;
mods[1] = NULL;
void ldap_close()
{
admin_bind = false;
- ldap_unbind(ld);
+ ldap_unbind_ext(ld, NULL, NULL);
+}
+
+/* queries the ldap server for account..
+ * returns LDAP_SUCCESS if a match is found
+ * returns LDAP_OTHER if no match is found
+ * on error returns the proper ldap error
+ */
+int ldap_user_exists(const char *account)
+{
+ int rc;
+ LDAPMessage *res;
+
+ rc = ldap_search_user(account, &res);
+
+ return rc;
}
#endif