Hi all,

I am experiencing a problem in ldap user authentication over SASL
+GSSAPI with a Microsoft AD 2003. After doing the "kinit", I have get
the first user ticket. But when I try to do a SASL bind with mechanism
GSSAPI, and try to give the same user principal that I gave to kinit
in the first SASL step that asks "Please enter your authorization
name" (code 0x4001), I get the service ticket (as shown by the klist
command), but my ldap sasl bind fails with the message

"LdapErr: DSID-0C09043E, comment: AcceptSecurityContext error, data
7a, vece"

with LDAP return code 49 means Invalid Credentials. I am using a
custom client here. The code is pasted after the environment details.
Please go through the code. By the way, I am getting the user and
service tickets from the AD server, its just the bind which is failing
in the SASL. In normal (simple bind), it is succeeding.

Here is the environment details

Server
=======
Microsoft Server 2003

Client
======
RedHat ES 3
MozillaLDAP 6.0.4
Cyrus-sasl 2.1.22


Client code
====================================================================

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>

#include <sasl.h>
#include <ldap.h>

static char progname[50];

//static int sasl_flags = LDAP_SASL_QUIET;
static int sasl_flags = LDAP_SASL_INTERACTIVE;
static char *sasl_mech = "GSSAPI";

static char buf[1024];

#define VALIDVAL(n) ((n >= SASL_CB_USER) && (n <= SASL_CB_GETREALM))


static char* getCString(char *strPtr, size_t sizeStrPtr, size_t
*strLength)
{
        int len = 0;

        if (strLength != NULL) *strLength = 0;

        if (strPtr && (strPtr = fgets(strPtr, sizeStrPtr, stdin)) != NULL)
        {
                len = strlen(strPtr);

                if ((len > 0) && (strPtr[len - 1] == '\n'))
                {
                        strPtr[len - 1] = '\0';
                        len--;
                }
                if (strLength != NULL) *strLength = len;
        }
        return strPtr;
}

static int
example_sasl_interact( LDAP *ld, unsigned flags, void *defaults, void
*prompts )
{
        //static times = 0;
        //printf(" -- Enter times : #%d\n", ++times);

        char *promptStrings[9] = {
                        "USER",
                        "AUTHNAME",
                        "LANGUAGE",
                        "PASS",
                        "ECHOPROMPT",
                        "NOECHOPROMPT",
                        "CNONCE",
                        "GETREALM",
                        NULL
                };

        sasl_interact_t         *interact = NULL;
        int                     rc;

        if (prompts == NULL) {
                return (LDAP_PARAM_ERROR);
        }

        int promptId = ((sasl_interact_t *)prompts)->id;
        int promptStringId = promptId - 0x4001;

        for (interact = prompts; interact->id != SASL_CB_LIST_END; interact+
+)
        {
        if (VALIDVAL(interact->id))
                {
                        printf(" >>   Prompt: [%x|%s] %s: ", promptId, 
(promptStringId >=0
&& promptStringId < 9 ? promptStrings[promptId-0x4001] : "N/A"),
interact->prompt?interact->prompt:"N/A");
                        getCString(buf, sizeof buf, NULL);
                interact->result = buf;
                interact->len = strlen(buf);
        }
        }
        return (LDAP_SUCCESS);
}

static int
usage(char *progname)
{
    fprintf(stderr, "Usage: %s [ debuglevel ]\n", progname);
    return 1;
}

int
main(int argc, char *argv[])
{
    int index;
    int rc;
    LDAP *ld;
    LDAPControl     **ctrls = NULL;
    int ldversion = LDAP_VERSION3;
    int debuglevel = 0;

        LDAPMessage     *result, *e;
        BerElement      *ber;
        char            *a, *dn;
        char            **vals;
        int             i;
        int     step = 1;

        strncpy(progname, argv[0], sizeof progname);

        if (argc == 2)
                debuglevel = atoi(argv[1]);
    /* set the default sasl args from the user input */
    else if (argc > 2)
                return usage(argv[0]);

        printf("============================================\n");
        printf("Starting ...\n\n");

    ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &debuglevel);
        /* get a handle to an LDAP connection */

        char serverName[100];
        int  serverPort=389;
        char serverBaseDN[512];
        char searchDN[1024];
        char searchFilter[512];

        printf("Step#%d) Enter LDAP server name|DNS|IP: ", step++);
        getCString(serverName, sizeof serverName, NULL);
        printf("Step#%d) Enter LDAP server port [389]: ", step++);
        getCString(buf, sizeof buf, NULL);
        serverPort=atoi(buf);

        if ( (ld = ldap_init( serverName, serverPort )) == NULL )
        {
                perror( "ldap_open" );
                return( 1 );
        }

    ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldversion );

        printf("Step#%d) Enter LDAP server base DN: ", step++);
        getCString(serverBaseDN, sizeof serverBaseDN, NULL);

        int s1 = step++;
        int s2 = step++;
        do {
                printf("Step#%d) Enter LDAP authentication method; 1) Simple
[default] 2) GSSAPI-Krb5 : ", s1);
                getCString(buf, sizeof buf, NULL);
                i = atoi(buf);
                if (i == 2)
                {
                        printf("Step#%d) Entering LDAP SASL authentication 
phase\n", s2);
                        
printf("--[Start]---------------------------------------\n");

                        LDAPControl     auth_resp_ctrl, *ctrl_array[ 3 ], 
**bindctrls;
                        LDAPControl pwpolicy_req_ctrl;
                        LDAPControl **ctrls = NULL;
                        LDAPControl **rctrls = NULL;

                        auth_resp_ctrl.ldctl_oid = LDAP_CONTROL_AUTH_REQUEST;
                        auth_resp_ctrl.ldctl_value.bv_val = NULL;
                        auth_resp_ctrl.ldctl_value.bv_len = 0;
                        auth_resp_ctrl.ldctl_iscritical = 0;
                        ctrl_array[0] = &auth_resp_ctrl;

                        pwpolicy_req_ctrl.ldctl_oid = 
LDAP_X_CONTROL_PWPOLICY_REQUEST;
                        pwpolicy_req_ctrl.ldctl_value.bv_val = NULL;
                        pwpolicy_req_ctrl.ldctl_value.bv_len = 0;
                        pwpolicy_req_ctrl.ldctl_iscritical = 0;
                        ctrl_array[1] = &pwpolicy_req_ctrl;
                        ctrl_array[2] = NULL;
                        bindctrls = ctrl_array;

                    rc = ldap_sasl_interactive_bind_ext_s( ld, serverBaseDN,
sasl_mech,
                                                           bindctrls, ctrls,
sasl_flags,
                                                           
example_sasl_interact,
NULL, &rctrls );
                        
printf("--[End]-----------------------------------------\n");

                }
                else
                {
                        printf("Step#%d) Launching LDAP simple BIND\n", s2);
                        
printf("--[Start]---------------------------------------\n");

                        char userName[100];
                        char userPass[100];
                        printf(" >>   Prompt: Enter user DN: ");
                        getCString(userName, sizeof userName, NULL);
                        printf(" >>   Prompt: Enter user passwd: ");
                        getCString(userPass, sizeof userPass, NULL);

                        rc = ldap_simple_bind_s( ld, userName, userPass );
                        
printf("--[End]-----------------------------------------\n");
                }
            if (rc == LDAP_SUCCESS )
                        break;

                sprintf(buf, "Bind Error [%d]", rc);
                ldap_perror( ld,  buf);

                printf("Do you want to try again ?[y/N] ");
            getCString(buf, sizeof buf, NULL);
        } while (buf[0] == 'y' || buf[0] == 'Y');

        if (rc != LDAP_SUCCESS )
                return ( 1 );

        sasl_ssf_t      ssf;
        unsigned long val = 0;
        if (!ldap_get_option(ld, LDAP_OPT_X_SASL_SSF, &ssf))
        {
                val = (unsigned long)ssf;
        }
        printf("Bind successful, security level is %lu\n", val);


    printf("Step#%d) Enter search DN: ", step++);
        getCString(searchDN, sizeof searchDN, NULL);
        printf("Step#%d) Enter search filter: ", step++);
        getCString(searchFilter, sizeof searchFilter, NULL);

        if ( (rc = ldap_search_s( ld, searchDN, LDAP_SCOPE_SUBTREE,
searchFilter, NULL, 0, &result )) != LDAP_SUCCESS )
        {
                sprintf(buf, "'ldap_search_s' Error [%d]", rc);
        ldap_perror( ld,  buf);
                if ( result == NULL )
                {
                        ldap_unbind( ld );
                        return( 1 );
                }
        }

        printf("Step#%d) LDAP search results\n", step++);
        printf("--[Start]---------------------------------------\n");
        /* for each entry print out name + all attrs and values */
        for ( e = ldap_first_entry( ld, result ); e != NULL; e =
ldap_next_entry( ld, e ) )
        {
                if ( (dn = ldap_get_dn( ld, e )) != NULL )
                {
                    printf( " => dn: %s\n", dn );
                    ldap_memfree( dn );
                }
                for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL; a =
ldap_next_attribute( ld, e, ber ) )
                {
                        if ((vals = ldap_get_values( ld, e, a)) != NULL )
                        {
                                for ( i = 0; vals[i] != NULL; i++ )
                                {
                                    printf( " --- %s: %s\n", a, vals[i] );
                                }
                                ldap_value_free( vals );
                        }
                        ldap_memfree( a );
                }
                if ( ber != NULL )
                {
                        ber_free( ber, 0 );
                }
                printf( ".\n" );
        }
        printf("--[End]-----------------------------------------\n\n
Terminating ...\n");
        ldap_msgfree( result );
        ldap_unbind( ld );
        return( 0 );
}



====================================================================


Kashif Ali Siddiqui
Tech Lead | Folio3 (www.folio3.com)
Email: [EMAIL PROTECTED]
_______________________________________________
dev-tech-ldap mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-ldap

Reply via email to