0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * GSSAPI Module
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * Copyright (c) 2005 Jelmer Vernooij <jelmer@samba.org>
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * Related standards:
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * - draft-ietf-sasl-gssapi-03
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen * Some parts inspired by an older patch from Colin Walters
e074ffeaee1ce283bd42f167c6810e3d013f8218Timo Sirainen * This software is released under the MIT license.
44fc0a34c39f1ddb3a776918630010867a5dd04eTimo Sirainen#if defined(BUILTIN_GSSAPI) || defined(PLUGIN_BUILD)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen/* Non-zero flags defined in RFC 2222 */
1fb790b0dadd9d7c226e5ff116355f447d68f31cTimo Sirainen { 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" };
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainenmech_gssapi_wrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf);
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainenstatic void mech_gssapi_log_error(struct auth_request *request,
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen (void)gss_display_status(&minor_status, status_value,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(request, AUTH_SUBSYS_MECH,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen str_sanitize(status_string.value, (size_t)-1));
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen (void)gss_release_buffer(&minor_status, &status_string);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen } while (message_context != 0);
1500468f62b0963974f1ba42a6ecf9c9be4381f4Timo Sirainenstatic void mech_gssapi_initialize(const struct auth_settings *set)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* environment may be used by Kerberos 5 library directly */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen env_put(t_strconcat("KRB5_KTNAME=", path, NULL));
448723dc1c12b126dd2d348d4ce385203abbaa7dTimo Sirainen#elif defined (HAVE_KRB5_GSS_REGISTER_ACCEPTOR_IDENTITY)
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic struct auth_request *mech_gssapi_auth_new(void)
1b81b28b2e7856748cffd7d01052a944b6c80b23Timo Sirainen pool = pool_alloconly_create(MEMPOOL_GROWING"gssapi_auth_request", 2048);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request = p_new(pool, struct gssapi_auth_request, 1);
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainenobtain_service_credentials(struct auth_request *request, gss_cred_id_t *ret_r)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen if (strcmp(request->set->gssapi_hostname, "$ALL") == 0) {
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_debug(request, AUTH_SUBSYS_MECH,
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen "Using all keytab entries");
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen if (strcasecmp(request->service, "POP3") == 0) {
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen /* The standard POP3 service name with GSSAPI is called
893f7d52acc42058045f188b625449981bd7f9bcTimo Sirainen just "pop". */
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen str_append(principal_name, request->set->gssapi_hostname);
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_debug(request, AUTH_SUBSYS_MECH,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen "Obtaining credentials for %s", str_c(principal_name));
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen inbuf.value = str_c_modifiable(principal_name);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_import_name(&minor_status, &inbuf,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(request, major_status, GSS_C_GSS_CODE,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen "importing principal name");
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_acquire_cred(&minor_status, gss_principal, 0,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(request, major_status, GSS_C_GSS_CODE,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen "acquiring service credentials");
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(request, minor_status, GSS_C_MECH_CODE,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen "acquiring service credentials");
da3f943e93b0ea5a8256a2e850f4738ad161f71dTimo Sirainen gss_release_name(&minor_status, &gss_principal);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenimport_name(struct auth_request *request, void *str, size_t len)
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen major_status = gss_import_name(&minor_status, &name_buf,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(request, major_status, GSS_C_GSS_CODE,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen "gss_import_name");
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainenduplicate_name(struct auth_request *request, gss_name_t old)
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen major_status = gss_duplicate_name(&minor_status, old, &new);
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen mech_gssapi_log_error(request, major_status, GSS_C_GSS_CODE,
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen "gss_duplicate_name");
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainenstatic bool data_has_nuls(const void *data, size_t len)
31803cddc7ad83490dbb71e84ed56954af64b8ceTimo Sirainen const unsigned char *c = data;
39f34a5a2c99a61aacb7e755e40d1cd221f68e86Timo Sirainen /* apparently all names end with NUL? */
31803cddc7ad83490dbb71e84ed56954af64b8ceTimo Sirainen for (i = 0; i < len; i++) {
31803cddc7ad83490dbb71e84ed56954af64b8ceTimo Sirainen if (c[i] == '\0')
7e770ce56e9123b9cadb3bff9d645b4420865a1aTimo Sirainenstatic int get_display_name(struct auth_request *auth_request, gss_name_t name,
7e770ce56e9123b9cadb3bff9d645b4420865a1aTimo Sirainen gss_OID *name_type_r, const char **display_name_r)
7e770ce56e9123b9cadb3bff9d645b4420865a1aTimo Sirainen major_status = gss_display_name(&minor_status, name,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(auth_request, major_status,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_MECH,
31803cddc7ad83490dbb71e84ed56954af64b8ceTimo Sirainen "authn_name has NULs");
7e770ce56e9123b9cadb3bff9d645b4420865a1aTimo Sirainen *display_name_r = t_strndup(buf.value, buf.length);
7e770ce56e9123b9cadb3bff9d645b4420865a1aTimo Sirainen (void)gss_release_buffer(&minor_status, &buf);
9c9332454f40a8c0ff53074d98ff86d607f76362Timo Sirainenstatic bool mech_gssapi_oid_cmp(const gss_OID_desc *oid1,
ace06232cfa0e99ecca1040e8553b3216d025768Timo Sirainen mem_equals_timing_safe(oid1->elements, oid2->elements, oid1->length);
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainenmech_gssapi_sec_context(struct gssapi_auth_request *request,
7e770ce56e9123b9cadb3bff9d645b4420865a1aTimo Sirainen struct auth_request *auth_request = &request->auth_request;
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(auth_request, major_status,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen "processing incoming data");
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(auth_request, minor_status,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen "processing incoming data");
1fb790b0dadd9d7c226e5ff116355f447d68f31cTimo Sirainen if (!mech_gssapi_oid_cmp(mech_type, &mech_gssapi_krb5_oid)) {
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_MECH,
9c9332454f40a8c0ff53074d98ff86d607f76362Timo Sirainen "GSSAPI mechanism not Kerberos5");
5f94d41239988988d70ed6ed7578306c60e77ed6Timo Sirainen } else if (get_display_name(auth_request, request->authn_name,
aef258ab477801df25b12929a7b9ab6d740d52f2Timo Sirainen else if (!auth_request_set_username(auth_request, username,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_MECH,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_debug(auth_request, AUTH_SUBSYS_MECH,
aef258ab477801df25b12929a7b9ab6d740d52f2Timo Sirainen "security context state completed.");
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_debug(auth_request, AUTH_SUBSYS_MECH,
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen "Processed incoming packet correctly, "
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen "waiting for another.");
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_error(auth_request, AUTH_SUBSYS_MECH,
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen "Received unexpected major status %d", major_status);
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen auth_request_handler_reply_continue(auth_request,
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen /* If there is no output token, go straight to wrap,
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen which is expecting an empty input token. */
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen ret = mech_gssapi_wrap(request, output_token);
aef258ab477801df25b12929a7b9ab6d740d52f2Timo Sirainen (void)gss_release_buffer(&minor_status, &output_token);
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainenmech_gssapi_wrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf)
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen /* The client's return data should be empty here */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen /* Only authentication, no integrity or confidentiality
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen protection (yet?) */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen major_status = gss_wrap(&minor_status, request->gss_ctx, 0,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(&request->auth_request, major_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_GSS_CODE, "sending security layer negotiation");
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(&request->auth_request, minor_status,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen GSS_C_MECH_CODE, "sending security layer negotiation");
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_debug(&request->auth_request, AUTH_SUBSYS_MECH,
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen "Negotiated security layer");
50782de8a9d5ebe11ee61496b4e695a1d3875230Timo Sirainen auth_request_handler_reply_continue(&request->auth_request,
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen (void)gss_release_buffer(&minor_status, &outbuf);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen request->sasl_gssapi_state = GSS_STATE_UNWRAP;
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainenk5_principal_is_authorized(struct auth_request *request, const char *name)
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen const char *value, *const *authorized_names, *const *tmp;
8521def0d87912647884064f4c549935cbdd0c7eTimo Sirainen value = auth_fields_find(request->extra_fields, "k5principals");
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen authorized_names = t_strsplit_spaces(value, ",");
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen for (tmp = authorized_names; *tmp != NULL; tmp++) {
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_debug(request, AUTH_SUBSYS_MECH,
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen "authorized by k5principals field: %s", name);
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainenmech_gssapi_krb5_userok(struct gssapi_auth_request *request,
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen /* Parse out the principal's username */
b1f02eab20719cda8ec4efe229dfd3c6967970f1Timo Sirainen if (get_display_name(&request->auth_request, name, &name_type,
9c9332454f40a8c0ff53074d98ff86d607f76362Timo Sirainen if (!mech_gssapi_oid_cmp(name_type, GSS_KRB5_NT_PRINCIPAL_NAME) &&
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(&request->auth_request, AUTH_SUBSYS_MECH,
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen "OID not kerberos principal name");
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen /* Init a krb5 context and parse the principal username */
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_error(&request->auth_request, AUTH_SUBSYS_MECH,
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen "krb5_init_context() failed: %d", (int)krb5_err);
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen krb5_err = krb5_parse_name(ctx, princ_display_name, &princ);
c869c075b0b558e82a613a8320b3b3a7e120741bTimo Sirainen /* writing the error string would be better, but we probably
c869c075b0b558e82a613a8320b3b3a7e120741bTimo Sirainen rarely get here and there doesn't seem to be a standard
c869c075b0b558e82a613a8320b3b3a7e120741bTimo Sirainen way of getting it */
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(&request->auth_request, AUTH_SUBSYS_MECH,
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen "krb5_parse_name() failed: %d",
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen /* See if the principal is in the list of authorized
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen * principals for the user */
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen authorized = k5_principal_is_authorized(&request->auth_request,
c5b99a8a85370e7d1f7edb1fcb18a9d44616f726Timo Sirainen /* See if the principal is authorized to act as the
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen specified (UNIX) user */
9a4542801f04f81385e554ba79b12f50eba1d460Stephan Bosch authorized = krb5_boolean2bool(krb5_kuserok(ctx, princ, login_user));
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainenmech_gssapi_userok(struct gssapi_auth_request *request, const char *login_user)
7e770ce56e9123b9cadb3bff9d645b4420865a1aTimo Sirainen struct auth_request *auth_request = &request->auth_request;
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen /* if authn and authz names equal, don't bother checking further. */
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen major_status = gss_compare_name(&minor_status,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(auth_request, major_status,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen "gss_compare_name failed");
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen /* handle cross-realm authentication */
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen /* Solaris */
44a9b5fc1b57e5cc0a113f8cada9d9011747cadcTimo Sirainen major_status = __gss_userok(&minor_status, request->authn_name,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(auth_request, major_status,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_MECH,
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen "User not authorized to log in as %s", login_user);
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen if (!mech_gssapi_krb5_userok(request, request->authn_name,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_MECH,
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen "User not authorized to log in as %s", login_user);
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_MECH,
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen "Cross-realm authentication not supported "
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen "(authn_name=%s, authz_name=%s)", request->auth_request.original_username, login_user);
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainengssapi_credentials_callback(enum passdb_result result,
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen /* We don't care much whether the lookup succeeded or not because GSSAPI
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen * does not strictly require a passdb. But if a passdb is configured,
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen * now the k5principals field will have been filled in. */
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen /* user is explicitly disabled, don't allow it to log in */
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen if (mech_gssapi_userok(gssapi_request, request->user) == 0)
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainenmech_gssapi_unwrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf)
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen struct auth_request *auth_request = &request->auth_request;
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen major_status = gss_unwrap(&minor_status, request->gss_ctx,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen mech_gssapi_log_error(auth_request, major_status,
f622620587322fda179727c06df79e162eb5ea8cTimo Sirainen "final negotiation: gss_unwrap");
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen /* outbuf[0] contains bitmask for selected security layer,
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen outbuf[1..3] contains maximum output_message size */
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_error(auth_request, AUTH_SUBSYS_MECH,
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen "Invalid response length");
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_MECH,
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen "authz_name has NULs");
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen login_user = p_strndup(auth_request->pool, name, name_len);
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen request->authz_name = import_name(auth_request, name, name_len);
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen request->authz_name = duplicate_name(auth_request,
0da7ec741f53fa8a2244421f6c63e0617b0cbf06Timo Sirainen if (get_display_name(auth_request, request->authz_name,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_MECH,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen "no authz_name");
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen /* Set username early, so that the credential lookup is for the
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen * authorizing user. This means the username in subsequent log
19557f192d37cd54a1a090a8a26d9d47265e4413Aki Tuomi * messages will be the authorization name, not the authentication
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen * name, which may mean that future log messages should be adjusted
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen * to log the right thing. */
7e770ce56e9123b9cadb3bff9d645b4420865a1aTimo Sirainen if (!auth_request_set_username(auth_request, login_user, &error)) {
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen auth_request_log_info(auth_request, AUTH_SUBSYS_MECH,
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen /* Continue in callback once auth_request is populated with passdb
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen information. */
8521def0d87912647884064f4c549935cbdd0c7eTimo Sirainen auth_request->passdb_success = TRUE; /* default to success */
00ef253647b45487e75b8a4a2636f38909eaee51Timo Sirainen auth_request_lookup_credentials(&request->auth_request, "",
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenmech_gssapi_auth_continue(struct auth_request *request,
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen ret = mech_gssapi_sec_context(gssapi_request, inbuf);
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen ret = mech_gssapi_wrap(gssapi_request, inbuf);
b55f6e163c6f20505bf4a57ccd085ee0609e92afTimo Sirainen ret = mech_gssapi_unwrap(gssapi_request, inbuf);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenmech_gssapi_auth_initial(struct auth_request *request,
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen gssapi_request->sasl_gssapi_state = GSS_STATE_SEC_CONTEXT;
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen /* The client should go first */
50782de8a9d5ebe11ee61496b4e695a1d3875230Timo Sirainen auth_request_handler_reply_continue(request, NULL, 0);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainen mech_gssapi_auth_continue(request, data, data_size);
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenmech_gssapi_auth_free(struct auth_request *request)
9e3f0cc69cbc4af74d08d1e52aa5ed8a7675b8f1Timo Sirainen if (gssapi_request->gss_ctx != GSS_C_NO_CONTEXT) {
fb51b3deffb527a6703b2077d5fc385fe31ea721Timo Sirainen (void)gss_release_cred(&minor_status, &gssapi_request->service_cred);
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen if (gssapi_request->authn_name != GSS_C_NO_NAME) {
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen if (gssapi_request->authz_name != GSS_C_NO_NAME) {
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen/* MTI Kerberos v1.5+ and Heimdal v0.7+ supports SPNEGO for Kerberos tickets
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen internally. Nothing else needs to be done here. Note however that this does
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen not support SPNEGO when the only available credential is NTLM.. */
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainenconst struct mech_module mech_gssapi_spnego = {
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen "GSS-SPNEGO",
fe813f74aaccb12f38e1bd9cd338c6a37fa646e5Timo Sirainen /* load if we already didn't load it using winbind */
3bc82073c6bc12195e4bb63c11ce546fdc0e8db3Timo Sirainen if (mech_module_find(mech_gssapi_spnego.mech_name) == NULL)
3bc82073c6bc12195e4bb63c11ce546fdc0e8db3Timo Sirainen mech = mech_module_find(mech_gssapi_spnego.mech_name);