/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
*/
/*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
* SPNEGO back-end for Kerberos. See [MS-KILE]
*/
#include <gssapi/gssapi_ext.h>
#include <gssapi/gssapi_krb5.h>
#include <krb5.h>
#include "smbd.h"
#include "smbd_authsvc.h"
typedef struct krb5ssp_backend {
char *be_username;
static uint32_t
static uint32_t
/*
* Initialize this context for Kerberos, if possible.
*
* Should not get here unless libsmb smb_config_get_negtok
* includes the Kerberos5 Mech OIDs in our spnego hint.
*
* Todo: allocate ctx->ctx_backend
* See: krb5_gss_accept_sec_context()
*/
int
{
if (be == 0)
return (NT_STATUS_NO_MEMORY);
return (0);
}
/*
* Todo: free ctx->ctx_backend
*/
void
{
return;
}
}
}
/*
* Handle a Kerberos auth message.
*
* State across messages is in ctx->ctx_backend
*/
int
{
/* Do this early, for error message support. */
if (kerr != 0) {
smbd_report("krb5ssp, krb5_init_ctx: %s",
return (NT_STATUS_INTERNAL_ERROR);
}
ctx->ctx_obodylen = 0;
} else {
}
smbd_report("krb5ssp: gss_accept_sec_context, "
"mech=0x%x, major=0x%x, minor=0x%x",
smbd_report(" krb5: %s",
return (NT_STATUS_WRONG_PASSWORD);
}
switch (major) {
case GSS_S_COMPLETE:
break;
case GSS_S_CONTINUE_NEEDED:
/* becomes NT_STATUS_MORE_PROCESSING_REQUIRED */
return (0);
}
return (NT_STATUS_WRONG_PASSWORD);
default:
return (NT_STATUS_WRONG_PASSWORD);
}
/*
* OK, we got GSS_S_COMPLETE. Get the name so we can use it
* in log messages if we get failures decoding the PAC etc.
* Then get the PAC, decode it, build the logon token.
*/
/* Save the user name. */
return (NT_STATUS_NO_MEMORY);
}
}
/*
* Extract the KRB5_AUTHDATA_WIN2K_PAC data.
*/
&be->be_authz_pac);
if (status)
return (status);
if (kerr) {
smbd_report("krb5ssp, krb5_pac_parse: %s",
return (NT_STATUS_UNSUCCESSFUL);
}
if (kerr) {
smbd_report("krb5ssp, krb5_pac_get_buffer: %s",
return (NT_STATUS_UNSUCCESSFUL);
}
return (NT_STATUS_NO_MEMORY);
if (status)
return (status);
if (status)
return (status);
return (NT_STATUS_UNSUCCESSFUL);
/* Success! */
return (0);
}
/*
* See: GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID
* and: KRB5_AUTHDATA_WIN2K_PAC
*/
static const gss_OID_desc
13, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0a\x81\x00" };
/*
* See: krb5_gss_inquire_sec_context_by_oid()
* and krb5_gss_inquire_sec_context_by_oid_ops[],
* gss_krb5int_extract_authz_data_from_sec_context()
*/
static uint32_t
{
goto out;
&minor,
&data_set);
smbd_report("krb5ssp, gss_inquire...PAC, "
goto out;
}
goto out;
}
/* Only need the first element? */
goto out;
}
status = 0;
out:
return (status);
}
/*
* Get the session key, and save it in the token.
*
* See: krb5_gss_inquire_sec_context_by_oid(),
* krb5_gss_inquire_sec_context_by_oid_ops[], and
* gss_krb5int_inq_session_key
*/
static uint32_t
{
smbd_report("krb5ssp, failed to get session key, "
goto out;
}
/*
* The key is in the first element
*/
if (data_set == GSS_C_NO_BUFFER_SET ||
smbd_report("krb5ssp: Session key is missing");
goto out;
}
smbd_report("krb5ssp: Session key too short (%d)",
goto out;
}
goto out;
}
status = 0;
out:
return (status);
}