/* * Compile: * gcc -o krb5_bind_test krb5_bind_test.c `krb5-config --libs` -lldap * * Run: * KRB5_TRACE=/dev/stderr ./krb5_bind_test */ #include #include #include #include #define TEST_PRINCIPAL "cifs/m17.ipa.local@IPA.LOCAL" #define TEST_URI "ldapi://%2fvar%2frun%2fslapd-IPA-LOCAL.socket" #define DEBUG(level, message) printf message; struct ipasam_sasl_interact_priv { krb5_context context; krb5_principal principal; krb5_keytab keytab; krb5_get_init_creds_opt *options; krb5_creds creds; krb5_ccache ccache; const char *name; int name_len; }; static int ldap_sasl_interact(LDAP *ld, unsigned flags, void *priv_data, void *sit) { sasl_interact_t *in = NULL; int ret = LDAP_OTHER; struct ipasam_sasl_interact_priv *data = (struct ipasam_sasl_interact_priv*) priv_data; if (!ld) return LDAP_PARAM_ERROR; for (in = sit; in && in->id != SASL_CB_LIST_END; in++) { switch(in->id) { case SASL_CB_USER: in->result = data->name; in->len = data->name_len; ret = LDAP_SUCCESS; DEBUG(0, ("Asked to provide username. Provided %s\n", (char*) in->result)); break; case SASL_CB_GETREALM: in->result = data->principal->realm.data; in->len = data->principal->realm.length; DEBUG(0, ("Asked to provide realm. Provided %s\n", (char*) in->result)); ret = LDAP_SUCCESS; break; default: in->result = NULL; in->len = 0; DEBUG(0, ("Got unrecognized request id %lu\n", in->id)); ret = LDAP_OTHER; } } return ret; } static int bind_callback(LDAP *ldap_struct, int use_default) { char *ccache_name = NULL; krb5_error_code rc; struct ipasam_sasl_interact_priv data; int ret; data.name = TEST_PRINCIPAL; data.name_len = strlen(data.name); rc = krb5_init_context(&data.context); rc = krb5_parse_name(data.context, data.name, &data.principal); DEBUG(0,("principal is %p (%d)\n", (void*) data.principal, rc)); if (use_default) { rc = krb5_cc_default(data.context, &data.ccache); } else { rc = krb5_cc_new_unique(data.context, "MEMORY", NULL, &data.ccache); } rc = krb5_cc_initialize(data.context, data.ccache, data.principal); rc = krb5_kt_resolve(data.context, "FILE:/etc/samba/samba.keytab", &data.keytab); DEBUG(0,("keytab is %p (%d)\n", (void*) data.keytab, rc)); rc = krb5_get_init_creds_opt_alloc(data.context, &data.options); DEBUG(0,("options are %p (%d)\n", (void*) data.options, rc)); rc = krb5_get_init_creds_opt_set_out_ccache(data.context, data.options, data.ccache); DEBUG(0,("options are using the ccache (%d)\n", rc)); rc = krb5_get_init_creds_keytab(data.context, &data.creds, data.principal, data.keytab, 0, NULL, data.options); DEBUG(0,("creds uses keytab (%d)\n", rc)); ret = ldap_sasl_interactive_bind_s(ldap_struct, NULL, "GSSAPI", NULL, NULL, LDAP_SASL_QUIET, ldap_sasl_interact, &data); DEBUG(0, ("bind result: %d\n", ret)); return ret; } int main(int argc, const char **argv) { LDAP *ld; int version; int ret; ret = ldap_initialize(&ld, TEST_URI); version = LDAP_VERSION3; ret = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version); ret = bind_callback(ld, (argc > 1)); ldap_unbind_ext(ld, NULL, NULL); return ret; }