X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fextra%2Fm_ldapauth.cpp;h=405bab082bef6df6522de1327408505ec533c9ef;hb=a5d110282a864fd2e91b51ce360a977cd0643657;hp=e2205ca8dc1d433d204ebe7b5dcda194d9e60fa1;hpb=1813369adecc1efc9812e90c40c21dc32e4965c9;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/extra/m_ldapauth.cpp b/src/modules/extra/m_ldapauth.cpp index e2205ca8d..405bab082 100644 --- a/src/modules/extra/m_ldapauth.cpp +++ b/src/modules/extra/m_ldapauth.cpp @@ -31,23 +31,23 @@ #include #ifdef _WIN32 -# pragma comment(lib, "ldap.lib") -# pragma comment(lib, "lber.lib") +# pragma comment(lib, "libldap.lib") +# pragma comment(lib, "liblber.lib") #endif /* $ModDesc: Allow/Deny connections based upon answer from LDAP server */ /* $LinkerFlags: -lldap */ -struct LDAPString +struct RAIILDAPString { char *str; - LDAPString(char *Str) + RAIILDAPString(char *Str) : str(Str) { } - ~LDAPString() + ~RAIILDAPString() { ldap_memfree(str); } @@ -63,6 +63,35 @@ struct LDAPString } }; +struct RAIILDAPMessage +{ + RAIILDAPMessage() + { + } + + ~RAIILDAPMessage() + { + dealloc(); + } + + void dealloc() + { + ldap_msgfree(msg); + } + + operator LDAPMessage*() + { + return msg; + } + + LDAPMessage **operator &() + { + return &msg; + } + + LDAPMessage *msg; +}; + class ModuleLDAPAuth : public Module { LocalIntExt ldapAuthed; @@ -92,8 +121,10 @@ public: void init() { + ServerInstance->Modules->AddService(ldapAuthed); + ServerInstance->Modules->AddService(ldapVhost); Implementation eventlist[] = { I_OnCheckReady, I_OnRehash,I_OnUserRegister, I_OnUserConnect }; - ServerInstance->Modules->Attach(eventlist, this, 4); + ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); OnRehash(NULL); } @@ -278,55 +309,48 @@ public: } } - LDAPMessage *msg, *entry; - std::string what = (attribute + "=" + (useusername ? user->ident : user->nick)); - if ((res = ldap_search_ext_s(conn, base.c_str(), searchscope, what.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg)) != LDAP_SUCCESS) + RAIILDAPMessage msg; + std::string what; + std::string::size_type pos = user->password.find(':'); + // If a username is provided in PASS, use it, othewrise user their nick or ident + if (pos != std::string::npos) { - // Do a second search, based on password, if it contains a : - // That is, PASS : will work. - size_t pos = user->password.find(":"); - if (pos != std::string::npos) - { - std::string cutpassword = user->password.substr(0, pos); - res = ldap_search_ext_s(conn, base.c_str(), searchscope, cutpassword.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg); - - if (res == LDAP_SUCCESS) - { - // Trim the user: prefix, leaving just 'pass' for later password check - user->password = user->password.substr(pos + 1); - } - } + what = (attribute + "=" + user->password.substr(0, pos)); - // It may have found based on user:pass check above. - if (res != LDAP_SUCCESS) - { - if (verbose) - ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (LDAP search failed: %s)", user->GetFullRealHost().c_str(), ldap_err2string(res)); - return false; - } + // Trim the user: prefix, leaving just 'pass' for later password check + user->password = user->password.substr(pos + 1); + } + else + { + what = (attribute + "=" + (useusername ? user->ident : user->nick)); + } + if ((res = ldap_search_ext_s(conn, base.c_str(), searchscope, what.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg)) != LDAP_SUCCESS) + { + if (verbose) + ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (LDAP search failed: %s)", user->GetFullRealHost().c_str(), ldap_err2string(res)); + return false; } if (ldap_count_entries(conn, msg) > 1) { if (verbose) ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (LDAP search returned more than one result: %s)", user->GetFullRealHost().c_str(), ldap_err2string(res)); - ldap_msgfree(msg); return false; } + + LDAPMessage *entry; if ((entry = ldap_first_entry(conn, msg)) == NULL) { if (verbose) ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (LDAP search returned no results: %s)", user->GetFullRealHost().c_str(), ldap_err2string(res)); - ldap_msgfree(msg); return false; } cred.bv_val = (char*)user->password.data(); cred.bv_len = user->password.length(); - LDAPString DN(ldap_get_dn(conn, entry)); + RAIILDAPString DN(ldap_get_dn(conn, entry)); if ((res = ldap_sasl_bind_s(conn, DN, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL)) != LDAP_SUCCESS) { if (verbose) ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (%s)", user->GetFullRealHost().c_str(), ldap_err2string(res)); - ldap_msgfree(msg); return false; } @@ -355,7 +379,6 @@ public: { if (verbose) ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (Lacks required LDAP attributes)", user->GetFullRealHost().c_str()); - ldap_msgfree(msg); return false; } } @@ -370,7 +393,7 @@ public: std::string dnPart; while (stream.GetToken(dnPart)) { - std::string::size_type pos = dnPart.find('='); + pos = dnPart.find('='); if (pos == std::string::npos) // malformed continue; @@ -383,7 +406,6 @@ public: ldapVhost.set(user, SafeReplace(vhost, dnParts)); } - ldap_msgfree(msg); ldapAuthed.set(user,1); return true; }