python-ldap: Unable to find a callback when using GSS-API
Question: I am trying to use python-ldap on Windows to query an Active Directory server.
This is what I have so far:

    
    
    import ldap
    import ldap.sasl
    
    email_address = 'user.name@host.company.com'
    ldap_url = 'ldap://domain.company.com:389'
    domain = 'domain'
    user = 'user'
    password = 'password'
    lo = ldap.initialize(ldap_url)
    auth_tokens = ldap.sasl.gssapi('')
    lo.sasl_interactive_bind_s('', auth_tokens)
    print lo.whoami_s()
    base = 'dc=%s,dc=company,dc=com' % domain
    scope = ldap.SCOPE_SUBTREE
    filter_str = '(mail=%s)' % email_address
    attr_list = None
    result = lo.search_s(base, scope, filter_str, attr_list)
    print "result = %s" % result
    

This is the traceback:

    
    
    Traceback (most recent call last):
    File "question.py", line 11, in <module>
    lo.sasl_interactive_bind_s('', auth_tokens)
    File "C:\Python27\lib\site-packages\ldap\ldapobject.py", line 244, in sasl_interactive_bind_s
    return self._ldap_call(self._l.sasl_interactive_bind_s,who,auth,RequestControlTuples(serverctrls),RequestControlTuples(clientctrls),sasl_flags)
    File "C:\Python27\lib\site-packages\ldap\ldapobject.py", line 106, in _ldap_call
    result = func(*args,**kwargs)
    ldap.LOCAL_ERROR: {'info': 'SASL(-1): generic failure: Unable to find a callback: 2', 'desc': 'Local error'}
    

I have used the [LDAP Admin](http://www.ldapadmin.org/download/ldapadmin.html)
tool to verify that I can reach the server from my Windows machine.

This is the code for ldap.sasl_interactive_bind_s:

    
    
    def sasl_interactive_bind_s(self,who,auth,serverctrls=None,clientctrls=None,sasl_flags=ldap.SASL_QUIET):
        """
        sasl_interactive_bind_s(who, auth [,serverctrls=None[,clientctrls=None[,sasl_flags=ldap.SASL_QUIET]]]) -> None
        """
        return self._ldap_call(self._l.sasl_interactive_bind_s,who,auth,RequestControlTuples(serverctrls),RequestControlTuples(clientctrls),sasl_flags)
    

SASL_QUIET is the default setting.


Answer: Cyrus SASL GSSAPI mechanism does not accept any authentication information
except a GSS credential struct at most. The error you see is that the
interactive mode requires a callback to supply dummy/default values. You need
to set to quiet/non-iternative mode.

Here is the code in C, you probably have to figure it out for Python:

    
    
    rc = ldap_sasl_interactive_bind_s(ld, NULL, SASL_MECH,
      NULL, NULL, LDAP_SASL_QUIET, do_interact, NULL);
    

where `do_interact` is:

    
    
    int do_interact(
             LDAP *ld,
             unsigned flags,
             void *defaults,
             void *in )
     {
       sasl_interact_t *interact = in;
       char *sasl_defaults = (char  *)defaults;
       const char *dflt = interact->defresult;
       dflt = sasl_defaults;
       interact->result = (dflt && *dflt) ? dflt : "";
       interact->len = strlen( interact->result );
       return LDAP_SUCCESS;
     }
    

Always remember that GSS-API always requires that you already have performed
authentication to network by other/external means, e.g., workstation login,
`kinit`, etc.

