Reputation: 1491
I am trying to figure out how to check if a user has a valid password with LDAP c++ code. This seems maddeningly difficult for what seems to be it's intended purpose.
The only working example code I could find was ldapsearch. I can log in as the default user and search for the user:
ldapsearch -x -D "cn=ldap,cn=Users,dc=company,dc=local" -W -H ldap://localhost:389 -b "ou=company_account,dc=company,dc=local" -s sub 'uid=my_id'
This seems to correspond to this code (note: lots of error checking removed)
LDAP *ld = NULL;
string sHostIP = session.ini["ldap_host"];
string sPort = session.ini["ldap_port"];
string sURL = sHostIP+":"+sPort;
ldap_initialize( &ld, sURL.c_str() );
int iVersion = LDAP_VERSION3;
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &iVersion );
string sLDAPPW = session.ini["ldap_server_pw"];
struct berval pServerPassword = { 0, NULL };
pServerPassword.bv_val = ber_strdup( &sLDAPPW[0] );
pServerPassword.bv_len = strlen( pServerPassword.bv_val );
//can't bind without this code block, but what does it even do?
int iMsgid;
int nsctrls = 0;
LDAPControl c;
c.ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYREQUEST;
c.ldctl_value.bv_val = NULL;
c.ldctl_value.bv_len = 0;
c.ldctl_iscritical = 0;
LDAPControl sctrl[3];
sctrl[nsctrls] = c;
LDAPControl *sctrls[4];
sctrls[nsctrls] = &sctrl[nsctrls];
sctrls[++nsctrls] = NULL;
LDAPControl **sctrlsp = NULL;
if ( nsctrls )
{
sctrlsp = sctrls;
}
KString sBindDN = session.ini["ldap_bind_dn"];
ldap_sasl_bind( ld, sBindDN.c_str(), LDAP_SASL_SIMPLE, &pServerPassword,sctrlsp, NULL, &iMsgid );
This is where, if we kept the hashed userPassword value I could search for a uid and userPassword combination. but since my company doesn't keep userPassword, that won't work.
I'm told that the other way to check the password is to bind as the user with the user password. But I need to use a different DN so I'm binding as user? Or I log in as the admin first then do a second bind as the user? And apparently this code is depreciated, but every non-depreciated example code I try to build crashes? Is there something I'm missing? Is there a good working example I use to authenticate users? I know apache can authenticate off of this LDAP server, but I don't know how.
Apache ldap.conf info here:
AuthLDAPURL "ldap://localhost:389/ou=company_account,dc=company,dc=local?sAMAccountName?sub?(objectClass=*)"
AuthLDAPBindDN "cn=ldap,cn=Users,dc=company,dc=local"
AuthLDAPBindPassword "removed"
Upvotes: 0
Views: 678
Reputation: 2078
you need just to perform ldap bind or sasl_bind
void TLDAP::sasl_simple_bind(const std::string & ldapDn, const std::string & ldapPw)
{
struct berval c_passwd = { 0, 0 };
c_passwd.bv_val = const_cast<char*>(ldapPw.c_str());
c_passwd.bv_len = ldapPw.size();
Check(ldap_sasl_bind_s(l.get(), ldapDn.c_str(), LDAP_SASL_SIMPLE, &c_passwd, NULL, NULL, NULL));
}
void TLDAP::simple_bind(const std::string & ldapDn, const std::string & ldapPw)
{
Check(ldap_simple_bind_s(l.get(), ldapDn.c_str(), ldapPw.c_str()));
}
ldap_simple_bind for non-encrypted connection, sasl_bind for encrypted
invocation example:
TLDAP::sasl_simple_bind("[email protected]", "1234asdf%^^&");
function Check just checks the return value and throws exception
Upvotes: 1