]> jfr.im git - irc/evilnet/x3.git/commitdiff
use ldap_add to add users to ldap when they register on irc
authorrubin <redacted>
Wed, 7 Feb 2007 15:14:17 +0000 (15:14 +0000)
committerrubin <redacted>
Wed, 7 Feb 2007 15:14:17 +0000 (15:14 +0000)
ChangeLog
src/nickserv.c
src/nickserv.h
src/x3ldap.c
src/x3ldap.h
x3.conf.example

index 487897ff0096a8a323ef8fcf81f617cb8fde6a14..ea12de3bd5a45c0c2906c246514029c779ef0dcc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,18 @@
 /***********************************************************************
 X3 ChangeLog
 
+2007-02-07  Alex Schumann  <rubin@afternet.org>
+
+       * src/x3ldap.c: ldap_add functionality
+
+       * src/x3ldap.h: ldap_add functionality
+
+       * src/nickserv.h: ldap_add functionality
+
+       * src/nickserv.c: ldap_add functionality
+
+       * x3.conf.example: ldap_add functionality
+
 2007-02-06  Alex Schumann  <rubin@afternet.org>
 
        * src/x3ldap.c: fix compiling problem when non-ldap. Compile fixups
index 7baeb2f0bc95e63a803ecd90726dd59859ad4c3a..838dcb7f3ffb431fe5c8b12a044648767be62575 100644 (file)
 #define KEY_LDAP_DN_FMT "ldap_dn_fmt"
 #define KEY_LDAP_VERSION "ldap_version"
 #define KEY_LDAP_AUTOCREATE "ldap_autocreate"
+#define KEY_LDAP_ADMIN_DN "ldap_admin_dn"
+#define KEY_LDAP_ADMIN_PASS "ldap_admin_pass"
+#define KEY_LDAP_FIELD_ACCOUNT "ldap_field_account"
+#define KEY_LDAP_FIELD_PASSWORD "ldap_field_password"
+#define KEY_LDAP_FIELD_EMAIL "ldap_field_email"
 #endif
 
 #define NICKSERV_VALID_CHARS   "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
@@ -1057,6 +1062,9 @@ nickserv_register(struct userNode *user, struct userNode *settee, const char *ha
     }
     if (settee && (user != settee))
         send_message(settee, nickserv, "NSMSG_OREGISTER_VICTIM", user->nick, hi->handle);
+#ifdef WITH_LDAP
+    ldap_do_add(handle, passwd, hi->email_addr);
+#endif
     return hi;
 }
 
@@ -4368,6 +4376,22 @@ nickserv_conf_read(void)
 
     str = database_get_data(conf_node, KEY_LDAP_AUTOCREATE, RECDB_QSTRING);
     nickserv_conf.ldap_autocreate = str ? strtoul(str, NULL, 0) : 0;
+
+    str = database_get_data(conf_node, KEY_LDAP_ADMIN_DN, RECDB_QSTRING);
+    nickserv_conf.ldap_admin_dn = str ? str : "";
+
+    str = database_get_data(conf_node, KEY_LDAP_ADMIN_PASS, RECDB_QSTRING);
+    nickserv_conf.ldap_admin_pass = str ? str : "";
+
+    str = database_get_data(conf_node, KEY_LDAP_FIELD_ACCOUNT, RECDB_QSTRING);
+    nickserv_conf.ldap_field_account = str ? str : "";
+
+    str = database_get_data(conf_node, KEY_LDAP_FIELD_PASSWORD, RECDB_QSTRING);
+    nickserv_conf.ldap_field_password = str ? str : "";
+
+    str = database_get_data(conf_node, KEY_LDAP_FIELD_EMAIL, RECDB_QSTRING);
+    nickserv_conf.ldap_field_email = str ? str : "";
+
 #endif
 
 }
index 6a3de2ff13cb02211fcac0b9720826f421174b2b..daa75d6cddcf1331bc808e27a7dcba33bdd4bf8e 100644 (file)
@@ -190,6 +190,12 @@ struct nickserv_config {
     const char *ldap_dn_fmt;
     unsigned int ldap_version;
     unsigned int ldap_autocreate;
+
+    const char *ldap_admin_dn;
+    const char *ldap_admin_pass;
+    const char *ldap_field_account;
+    const char *ldap_field_password;
+    const char *ldap_field_email;
 #endif
 };
 
index 236dd194c078346aedad28ee41943d21cbe9350b..426b5e76c8bc2e57f5996a03058cbe17abc9a18b 100644 (file)
@@ -75,35 +75,30 @@ int ldap_do_init()
    return true;
 }
 
+
 /* Try to auth someone. If theres problems, try reconnecting 
  * once every 10 seconds for 1 minute.
  * TODO: move this stuff to config file
  */
-unsigned int ldap_check_auth( char *account, char *pass)
+unsigned int ldap_do_bind( const char *dn, const char *pass)
 {
-   char buff[MAXLEN];
    int q;
 
-   if(!nickserv_conf.ldap_enable)
-     return false;
-
-   memset(buff, 0, MAXLEN);
-   snprintf(buff, sizeof(buff)-1, nickserv_conf.ldap_dn_fmt /*"uid=%s,ou=Users,dc=afternet,dc=org"*/, account);
    int n = 0;
    while(1) {
-      q = ldap_simple_bind_s(ld, buff, pass);
+      q = ldap_simple_bind_s(ld, dn, pass);
       if(q == LDAP_SUCCESS) {
-         return true;
+           log_module(MAIN_LOG, LOG_DEBUG, "bind() successfull! You are bound as %s\n", dn);
+           /* unbind now */
+           return true;
       }
       else if(q == LDAP_INVALID_CREDENTIALS) {
         return false;
       }
       else {
-        log_module(MAIN_LOG, LOG_ERROR, "Bind failed: %s/******  (%d)\n", buff, q);
+        log_module(MAIN_LOG, LOG_ERROR, "Bind failed: %s/******  (%d)\n", dn, q);
         ldap_perror(ld, "ldap");
-        /* Re-init to re-connect to ldap server if thats the problem */
-        //sleep(10);
-        ldap_do_init(nickserv_conf);
+        ldap_do_init();
       }
       if(n++ > 1) {
          /* TODO: return to the user that this is a connection error and not a problem
@@ -113,8 +108,20 @@ unsigned int ldap_check_auth( char *account, char *pass)
          return false;
       }
    }
-   log_module(MAIN_LOG, LOG_DEBUG, "bind() successfull! You are bound as %s\n", buff);
-   return true;
+   log_module(MAIN_LOG, LOG_ERROR, "ldap_do_bind falling off the end. this shouldnt happen");
+   return false;
+}
+
+unsigned int ldap_check_auth( char *account, char *pass)
+{
+   char buff[MAXLEN];
+
+   if(!nickserv_conf.ldap_enable)
+     return false;
+
+   memset(buff, 0, MAXLEN);
+   snprintf(buff, sizeof(buff)-1, nickserv_conf.ldap_dn_fmt /*"uid=%s,ou=Users,dc=afternet,dc=org"*/, account);
+   return ldap_do_bind(buff, pass);
 
 }
 
@@ -166,6 +173,102 @@ LDAPMessage ldap_search_user(char uid)
 
 #endif
 
+LDAPMod **make_mods(const char *account, const char *password, const char *email, int *num_mods_ret)
+{
+    static char *account_vals[] = { NULL, NULL };
+    static char *password_vals[] = { NULL, NULL };
+    static char *email_vals[] = { NULL, NULL };
+    char newdn[MAXLEN];
+    int num_mods = 3;
+    int i;
+    /* TODO: take this from nickserv_conf.ldap_add_objects */
+    static char *object_vals[] = { "top", "inetOrgAnonAccount", NULL };
+    LDAPMod **mods;
+
+    account_vals[0] = (char *) account;
+    password_vals[0] = (char *) password;
+    email_vals[0] = (char *) email;
+
+    if(!(nickserv_conf.ldap_field_account && *nickserv_conf.ldap_field_account))
+       return 0; /* account required */
+    if(!(nickserv_conf.ldap_field_password && *nickserv_conf.ldap_field_password))
+       return 0; /* password required */
+    if(email && *email && nickserv_conf.ldap_field_email && *nickserv_conf.ldap_field_email)
+       num_mods++;
+
+    mods = ( LDAPMod ** ) malloc(( num_mods + 1 ) * sizeof( LDAPMod * ));
+    for( i = 0; i < num_mods; i++) {
+      mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
+      memset(mods[i], 0, sizeof(LDAPMod));
+    }
+
+    memset(newdn, 0, MAXLEN);
+    mods[0]->mod_op = LDAP_MOD_ADD;
+    mods[0]->mod_type = strdup("objectclass");
+    mods[0]->mod_values = object_vals;
+
+    mods[1]->mod_op = LDAP_MOD_ADD;
+    mods[1]->mod_type = strdup(nickserv_conf.ldap_field_account);
+    mods[1]->mod_values = account_vals;
+
+    mods[2]->mod_op = LDAP_MOD_ADD;
+    mods[2]->mod_type = strdup(nickserv_conf.ldap_field_password);
+    mods[2]->mod_values = password_vals;
+
+    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;
+    }
+    else
+       mods[3] = NULL;
+    *num_mods_ret = num_mods;
+    return mods;
+}
+
+int ldap_do_admin_bind()
+{
+   if(!(nickserv_conf.ldap_admin_dn && *nickserv_conf.ldap_admin_dn && 
+      nickserv_conf.ldap_admin_pass && *nickserv_conf.ldap_admin_pass)) {
+       log_module(MAIN_LOG, LOG_ERROR, "Tried to admin bind, but no admin credentials configured in config file. ldap_admin_dn/ldap_admin_pass");
+       return false; /* not configured to do this */
+    }
+    return(ldap_do_bind(nickserv_conf.ldap_admin_dn, nickserv_conf.ldap_admin_pass));
+}
+
+int ldap_do_add(const char *account, const char *password, const char *email)
+{
+    char newdn[MAXLEN];
+    LDAPMod **mods;
+    int rc, i;
+    int num_mods;
+    
+    if(!( rc = ldap_do_admin_bind())) {
+       log_module(MAIN_LOG, LOG_ERROR, "failed to bind as admin");
+       return false;
+    }
+    
+    snprintf(newdn, MAXLEN-1, nickserv_conf.ldap_dn_fmt, account);
+    mods = make_mods(account, password, email, &num_mods);
+    if(!mods) {
+       log_module(MAIN_LOG, LOG_ERROR, "Error building mods for ldap_add");
+       return false;
+    }
+    rc = ldap_add_ext_s(ld, newdn, mods, NULL, NULL);
+    if(rc != LDAP_SUCCESS) {
+       log_module(MAIN_LOG, LOG_ERROR, "Error adding ldap account: %s -- %s", account, ldap_err2string(rc));
+       return false;
+    }
+    //ldap_unbind_s(ld);
+    for(i = 0; i < num_mods; i++) {
+       free(mods[i]->mod_type);
+       free(mods[i]);
+    }
+    free(mods);
+    return true;
+}
+
 void ldap_close()
 {
    ldap_unbind(ld);
index a6a48a6f88befa4515f6325184a3eb148f672fc3..1dc5e2b80fbe88e693c44d4ccf6fa4a8b94bab75 100644 (file)
@@ -25,6 +25,7 @@
 int ldap_do_init();
 
 unsigned int ldap_check_auth(char *account, char *pass);
+int ldap_do_add(const char *account, const char *password, const char *email);
 
 void ldap_close();
 
index e66e118b2fe65ffa260409825988562bbb684a94..67771dfc7b4e620b8cf68d6cb8cc5a36a6846ce4 100644 (file)
         //"ldap_dn_fmt" "uid=%s,ou=Users,dc=afternet,dc=org";
         // automatically create accounts if they exist in ldap but not x3
         //"ldap_autocreate" "1"; 
+        //
+        // If you will be allowing users to register on IRC you need these:
+        //"ldap_admin_dn" "cn=Admin,dc=afternet,dc=org";
+        //"ldap_admin_pass" "xyzzyx";
+        //"ldap_add_objects" ( "top", "inetOrgAnon" );
+        //      NOTE: inetOrgAnon is something I made up. its schema
+        //      can be found in the tools/ directory. ldap servers wont
+        //      know what that is by default.
+        // These configure what I store, and where.
+        //"ldap_add_account" "uid";
+        //"ldap_add_password "userPassword";
+        //"ldap_add_email" "";
     };
 
     /*