How to authenticate to Active Directory using gsasl gssapi?

Viewed 187

I'm trying to authenticate to an Active Directory domain using gsasl. I've already kinit'd as the Administrator. I've tried to follow the test code in gsasl tests/gssapi.c, but the code below is failing with GSASL_GSSAPI_INIT_SEC_CONTEXT_ERROR when calling gsasl_step64().

static int callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop)
{
    int ret = GSASL_NO_CALLBACK;

    switch (prop) {
        case GSASL_AUTHZID:
            gsasl_property_set(sctx, GSASL_AUTHZID, "Administrator");
            ret = GSASL_OK;
            break;

        case GSASL_SERVICE:
            gsasl_property_set(sctx, prop, "host");
            ret = GSASL_OK;
            break;

        case GSASL_HOSTNAME:
            char hostname[HOST_NAME_MAX];
            gethostname(hostname, HOST_NAME_MAX);
            gsasl_property_set(sctx, prop, hostname);
            ret = GSASL_OK;
            break;

        default:
            break;
    }

    return ret;
}

int main()
{
    Gsasl *ctx = NULL;
    Gsasl_session *session;
    char *s1 = NULL, *s2 = NULL;
    int ret;

    ret = gsasl_init(&ctx);
    if (ret != GSASL_OK) {
        cerr << "gsasl_init failed" << endl;
        return ret;
    }

    if (!gsasl_client_support_p(ctx, "GSSAPI")) {
        cerr << "No support for GSSAPI." << endl;
        return 77;
    }

    gsasl_callback_set(ctx, callback);

    ret = gsasl_client_start(ctx, "GSSAPI", &session);
    if (ret != GSASL_OK) {
        cerr << "gsasl_client_start failed" << endl;
        return ret;
    }

    do {
        ret = gsasl_step64(session, s2, &s1);
        gsasl_free(s2);
        if (ret != GSASL_OK && ret != GSASL_NEEDS_MORE) {
            cerr << "gsasl_step64 failed " << ret << endl;
            return ret;
        }
    } while (ret != GSASL_OK);

    if (s1) {
        gsasl_free(s1);
    }

    gsasl_finish(session);
}

Does anyone see what I'm doing wrong?

1 Answers

Not really a clear answer because I don't use AD currently, so I can't verify my answer. But to localize the issue:

I would try the examples first. Maybe this test is desired to fail. If it doesn't work with the examples, I would investigate the source of library of the GNU SASL library.

Here is an extract from the source of the library, which throws this error:

maj_stat = gss_init_sec_context (&min_stat,
                                    GSS_C_NO_CREDENTIAL,
                                    &state->context,
                                    state->service,
                                    state->mech_oid,
                                    GSS_C_MUTUAL_FLAG,
                                     0,
                                    &state->cb,
                                    buf,
                                    &actual_mech_type,
                                    &state->token, &ret_flags, NULL);

if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
    return GSASL_GSSAPI_INIT_SEC_CONTEXT_ERROR;

As you can see, the function gss_init_sec_context() is called, In the if clause only GSS_S_COMPLETE and GSS_S_CONTINUE_NEEDED will be tested. But gss_init_sec_context() has many more status codes. So I would change the code of the library and print out a clearer error code, why it doesn't work.

There was also an issue in WINBIND/SAMBA, don't know if you use SAMBA, which throws an unspecified error in this specific function.

Related