00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "inspircd.h"
00025 #include "users.h"
00026 #include "channels.h"
00027 #include "modules.h"
00028
00029 #include <ldap.h>
00030
00031
00032
00033
00034 class ModuleLDAPAuth : public Module
00035 {
00036 std::string base;
00037 std::string ldapserver;
00038 std::string username;
00039 std::string password;
00040 int searchscope;
00041 LDAP *conn;
00042
00043 public:
00044 ModuleLDAPAuth(InspIRCd* Me)
00045 : Module(Me)
00046 {
00047 conn = NULL;
00048 Implementation eventlist[] = { I_OnRehash, I_OnPassCompare };
00049 ServerInstance->Modules->Attach(eventlist, this, 2);
00050 OnRehash(NULL,"");
00051 }
00052
00053 virtual ~ModuleLDAPAuth()
00054 {
00055 if (conn)
00056 ldap_unbind_ext(conn, NULL, NULL);
00057 }
00058
00059 virtual void OnRehash(User* user, const std::string ¶meter)
00060 {
00061 ConfigReader Conf(ServerInstance);
00062
00063 base = Conf.ReadValue("ldapoper", "baserdn", 0);
00064 ldapserver = Conf.ReadValue("ldapoper", "server", 0);
00065 std::string scope = Conf.ReadValue("ldapoper", "searchscope", 0);
00066 username = Conf.ReadValue("ldapoper", "binddn", 0);
00067 password = Conf.ReadValue("ldapoper", "bindauth", 0);
00068
00069 if (scope == "base")
00070 searchscope = LDAP_SCOPE_BASE;
00071 else if (scope == "onelevel")
00072 searchscope = LDAP_SCOPE_ONELEVEL;
00073 else searchscope = LDAP_SCOPE_SUBTREE;
00074
00075 Connect();
00076 }
00077
00078 bool Connect()
00079 {
00080 if (conn != NULL)
00081 ldap_unbind_ext(conn, NULL, NULL);
00082 int res, v = LDAP_VERSION3;
00083 res = ldap_initialize(&conn, ldapserver.c_str());
00084 if (res != LDAP_SUCCESS)
00085 {
00086 conn = NULL;
00087 return false;
00088 }
00089
00090 res = ldap_set_option(conn, LDAP_OPT_PROTOCOL_VERSION, (void *)&v);
00091 if (res != LDAP_SUCCESS)
00092 {
00093 ldap_unbind_ext(conn, NULL, NULL);
00094 conn = NULL;
00095 return false;
00096 }
00097 return true;
00098 }
00099
00100 virtual int OnPassCompare(Extensible* ex, const std::string &data, const std::string &input, const std::string &hashtype)
00101 {
00102 User* user = dynamic_cast<User*>(ex);
00103 if (hashtype == "ldap")
00104 {
00105 if (LookupOper(user, data, input))
00106 {
00107
00108 return 1;
00109 }
00110 }
00111
00112 return 0;
00113 }
00114
00115 bool LookupOper(User* user, const std::string &what, const std::string &opassword)
00116 {
00117 if (conn == NULL)
00118 if (!Connect())
00119 return false;
00120
00121 int res;
00122 char* authpass = strdup(password.c_str());
00123
00124 struct berval cred;
00125 cred.bv_val = authpass;
00126 cred.bv_len = password.length();
00127
00128 if ((res = ldap_sasl_bind_s(conn, username.c_str(), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL)) != LDAP_SUCCESS)
00129 {
00130 free(authpass);
00131 ldap_unbind_ext(conn, NULL, NULL);
00132 conn = NULL;
00133 return false;
00134 }
00135 free(authpass);
00136
00137 LDAPMessage *msg, *entry;
00138 if ((res = ldap_search_ext_s(conn, base.c_str(), searchscope, what.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg)) != LDAP_SUCCESS)
00139 {
00140 return false;
00141 }
00142 if (ldap_count_entries(conn, msg) > 1)
00143 {
00144 ldap_msgfree(msg);
00145 return false;
00146 }
00147 if ((entry = ldap_first_entry(conn, msg)) == NULL)
00148 {
00149 ldap_msgfree(msg);
00150 return false;
00151 }
00152 authpass = strdup(opassword.c_str());
00153 cred.bv_val = authpass;
00154 cred.bv_len = opassword.length();
00155 if ((res = ldap_sasl_bind_s(conn, ldap_get_dn(conn, entry), LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL)) == LDAP_SUCCESS)
00156 {
00157 free(authpass);
00158 ldap_msgfree(msg);
00159 return true;
00160 }
00161 else
00162 {
00163 free(authpass);
00164 ldap_msgfree(msg);
00165 return false;
00166 }
00167 }
00168
00169 virtual Version GetVersion()
00170 {
00171 return Version("$Id: m_ldapoper.cpp 10394 2008-09-05 11:22:50Z brain $", VF_VENDOR, API_VERSION);
00172 }
00173
00174 };
00175
00176 MODULE_INIT(ModuleLDAPAuth)