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;
}
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;
#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;
#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,
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);
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;