From b55f6e163c6f20505bf4a57ccd085ee0609e92af Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 7 Jul 2009 21:05:31 -0400 Subject: [PATCH] gssapi: Use *userok() functions only when authz_name != authn_name. Some more code cleanups. --HG-- branch : HEAD --- src/auth/mech-gssapi.c | 128 +++++++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 56 deletions(-) diff --git a/src/auth/mech-gssapi.c b/src/auth/mech-gssapi.c index ee1ebf758c..62a8a9e77c 100644 --- a/src/auth/mech-gssapi.c +++ b/src/auth/mech-gssapi.c @@ -233,8 +233,9 @@ static int get_display_name(struct auth_request *auth_request, gss_name_t name, return 0; } -static int gssapi_sec_context(struct gssapi_auth_request *request, - gss_buffer_desc inbuf) +static int +mech_gssapi_sec_context(struct gssapi_auth_request *request, + gss_buffer_desc inbuf) { struct auth_request *auth_request = &request->auth_request; OM_uint32 major_status, minor_status; @@ -299,7 +300,7 @@ static int gssapi_sec_context(struct gssapi_auth_request *request, } static int -gssapi_wrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf) +mech_gssapi_wrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf) { OM_uint32 major_status, minor_status; gss_buffer_desc outbuf; @@ -343,9 +344,9 @@ gssapi_wrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf) #ifdef USE_KRB5_USEROK static bool -gssapi_krb5_userok(struct gssapi_auth_request *request, - gss_name_t name, const char *login_user, - bool check_name_type) +mech_gssapi_krb5_userok(struct gssapi_auth_request *request, + gss_name_t name, const char *login_user, + bool check_name_type) { krb5_context ctx; krb5_principal princ; @@ -392,52 +393,35 @@ gssapi_krb5_userok(struct gssapi_auth_request *request, #endif static int -gssapi_unwrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf) +mech_gssapi_userok(struct gssapi_auth_request *request, const char *login_user) { struct auth_request *auth_request = &request->auth_request; OM_uint32 major_status, minor_status; - gss_buffer_desc outbuf; - const char *login_user, *error; - unsigned char *name; - unsigned int name_len; -#if defined(HAVE___GSS_USEROK) - int login_ok; -#elif !defined(USE_KRB5_USEROK) int equal_authn_authz; +#ifdef HAVE___GSS_USEROK + int login_ok; #endif - major_status = gss_unwrap(&minor_status, request->gss_ctx, - &inbuf, &outbuf, NULL, NULL); - + /* if authn and authz names equal, don't bother checking further. */ + major_status = gss_compare_name(&minor_status, + request->authn_name, + request->authz_name, + &equal_authn_authz); if (GSS_ERROR(major_status)) { auth_request_log_gss_error(auth_request, major_status, GSS_C_GSS_CODE, - "final negotiation: gss_unwrap"); - return -1; - } - - /* outbuf[0] contains bitmask for selected security layer, - outbuf[1..3] contains maximum output_message size */ - if (outbuf.length <= 4) { - auth_request_log_error(auth_request, "gssapi", - "Invalid response length"); + "gss_compare_name failed"); return -1; } - name = (unsigned char *)outbuf.value + 4; - name_len = outbuf.length - 4; - login_user = p_strndup(auth_request->pool, name, name_len); - request->authz_name = import_name(auth_request, name, name_len); - if (request->authz_name == GSS_C_NO_NAME) { - auth_request_log_info(auth_request, "gssapi", "no authz_name"); - return -1; - } + if (equal_authn_authz != 0) + return 0; + /* handle cross-realm authentication */ #ifdef HAVE___GSS_USEROK - /* Solaris __gss_userok() correctly handles cross-realm - authentication. */ + /* Solaris */ major_status = __gss_userok(&minor_status, request->authn_name, - auth_request->user, &login_ok); + login_user, &login_ok); if (GSS_ERROR(major_status)) { auth_request_log_gss_error(auth_request, major_status, GSS_C_GSS_CODE, @@ -447,41 +431,73 @@ gssapi_unwrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf) if (login_ok == 0) { auth_request_log_info(auth_request, "gssapi", - "credentials not valid"); + "User not authorized to log in as %s", login_user); return -1; } + return 0; #elif defined(USE_KRB5_USEROK) - if (!gssapi_krb5_userok(request, request->authn_name, - login_user, TRUE)) { + if (!mech_gssapi_krb5_userok(request, request->authn_name, + login_user, TRUE)) { auth_request_log_info(auth_request, "gssapi", - "authn_name (%s) not authorized to log in as %s", - auth_request->user, login_user); + "User not authorized to log in as %s", login_user); return -1; } - if (!gssapi_krb5_userok(request, request->authz_name, - login_user, FALSE)) { + if (!mech_gssapi_krb5_userok(request, request->authz_name, + login_user, FALSE)) { auth_request_log_info(auth_request, "gssapi", "authz_name (%s) not authorized", login_user); return -1; } + return 0; #else - major_status = gss_compare_name(&minor_status, - request->authn_name, - request->authz_name, - &equal_authn_authz); + auth_request_log_info(auth_request, "gssapi", + "Cross-realm authentication not supported " + "(authz_name=%s)", login_user); + return -1; +#endif +} + +static int +mech_gssapi_unwrap(struct gssapi_auth_request *request, gss_buffer_desc inbuf) +{ + struct auth_request *auth_request = &request->auth_request; + OM_uint32 major_status, minor_status; + gss_buffer_desc outbuf; + const char *login_user, *error; + unsigned char *name; + unsigned int name_len; + + major_status = gss_unwrap(&minor_status, request->gss_ctx, + &inbuf, &outbuf, NULL, NULL); + if (GSS_ERROR(major_status)) { auth_request_log_gss_error(auth_request, major_status, GSS_C_GSS_CODE, - "gss_compare_name failed"); + "final negotiation: gss_unwrap"); + return -1; + } + + /* outbuf[0] contains bitmask for selected security layer, + outbuf[1..3] contains maximum output_message size */ + if (outbuf.length <= 4) { + auth_request_log_error(auth_request, "gssapi", + "Invalid response length"); return -1; } - if (equal_authn_authz == 0) { - auth_request_log_info(auth_request, "gssapi", - "authn_name and authz_name differ: not supported"); + name = (unsigned char *)outbuf.value + 4; + name_len = outbuf.length - 4; + + login_user = p_strndup(auth_request->pool, name, name_len); + request->authz_name = import_name(auth_request, name, name_len); + if (request->authz_name == GSS_C_NO_NAME) { + auth_request_log_info(auth_request, "gssapi", "no authz_name"); return -1; } -#endif + + if (mech_gssapi_userok(request, login_user) < 0) + return -1; + if (!auth_request_set_username(auth_request, login_user, &error)) { auth_request_log_info(auth_request, "gssapi", "authz_name: %s", error); @@ -506,13 +522,13 @@ mech_gssapi_auth_continue(struct auth_request *request, switch (gssapi_request->sasl_gssapi_state) { case GSS_STATE_SEC_CONTEXT: - ret = gssapi_sec_context(gssapi_request, inbuf); + ret = mech_gssapi_sec_context(gssapi_request, inbuf); break; case GSS_STATE_WRAP: - ret = gssapi_wrap(gssapi_request, inbuf); + ret = mech_gssapi_wrap(gssapi_request, inbuf); break; case GSS_STATE_UNWRAP: - ret = gssapi_unwrap(gssapi_request, inbuf); + ret = mech_gssapi_unwrap(gssapi_request, inbuf); break; default: ret = -1; -- 2.47.3