1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-24 21:49:29 +03:00

Fix Kerberos interop with Mac OS X 10.5 clients.

Ignore optional req_flags. Use the Kerberos mechanism OID negotiated
with the client rather than hardcoding OID_KERBEROS5_OLD.
This commit is contained in:
Bill Ricker
2008-04-07 15:02:56 -07:00
committed by James Peach
parent fd168e7b50
commit 59a2bcf30f
3 changed files with 45 additions and 23 deletions

View File

@ -246,6 +246,18 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se
asn1_end_tag(&data);
asn1_end_tag(&data);
/* Skip any optional req_flags that are sent per RFC 4178 */
if (asn1_check_tag(&data, ASN1_CONTEXT(1))) {
uint8 flags;
asn1_start_tag(&data, ASN1_CONTEXT(1));
asn1_start_tag(&data, ASN1_BITFIELD);
while (asn1_tag_remaining(&data) > 0)
asn1_read_uint8(&data, &flags);
asn1_end_tag(&data);
asn1_end_tag(&data);
}
asn1_start_tag(&data, ASN1_CONTEXT(2));
asn1_read_OctetString(&data,secblob);
asn1_end_tag(&data);

View File

@ -484,10 +484,11 @@ static NTSTATUS srv_enc_spnego_negotiate(connection_struct *conn,
DATA_BLOB blob = data_blob_null;
DATA_BLOB secblob = data_blob_null;
bool got_kerberos_mechanism = false;
char *kerb_mech = NULL;
blob = data_blob_const(*ppdata, *p_data_size);
status = parse_spnego_mechanisms(blob, &secblob, &got_kerberos_mechanism);
status = parse_spnego_mechanisms(blob, &secblob, &kerb_mech);
if (!NT_STATUS_IS_OK(status)) {
return nt_status_squash(status);
}
@ -496,7 +497,9 @@ static NTSTATUS srv_enc_spnego_negotiate(connection_struct *conn,
srv_free_encryption_context(&partial_srv_trans_enc_ctx);
if (got_kerberos_mechanism) {
if (kerb_mech) {
SAFE_FREE(kerb_mech);
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
status = srv_enc_spnego_gss_negotiate(ppdata, p_data_size, secblob);
#else

View File

@ -248,6 +248,7 @@ static bool make_krb5_skew_error(DATA_BLOB *pblob_out)
static void reply_spnego_kerberos(struct smb_request *req,
DATA_BLOB *secblob,
const char *mechOID,
uint16 vuid,
bool *p_invalidate_vuid)
{
@ -598,7 +599,7 @@ static void reply_spnego_kerberos(struct smb_request *req,
ap_rep_wrapped = data_blob_null;
}
response = spnego_gen_auth_response(&ap_rep_wrapped, ret,
OID_KERBEROS5_OLD);
mechOID);
reply_sesssetup_blob(req, response, ret);
data_blob_free(&ap_rep);
@ -709,13 +710,15 @@ static void reply_spnego_ntlmssp(struct smb_request *req,
Is this a krb5 mechanism ?
****************************************************************************/
NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out,
bool *p_is_krb5)
NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in,
DATA_BLOB *pblob_out,
char **kerb_mechOID)
{
char *OIDs[ASN1_MAX_OIDS];
int i;
NTSTATUS ret = NT_STATUS_OK;
*p_is_krb5 = False;
*kerb_mechOID = NULL;
/* parse out the OIDs and the first sec blob */
if (!parse_negTokenTarg(blob_in, OIDs, pblob_out)) {
@ -735,7 +738,10 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out,
#ifdef HAVE_KRB5
if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
*p_is_krb5 = True;
*kerb_mechOID = SMB_STRDUP(OIDs[0]);
if (*kerb_mechOID == NULL) {
ret = NT_STATUS_NO_MEMORY;
}
}
#endif
@ -743,7 +749,7 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out,
DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
free(OIDs[i]);
}
return NT_STATUS_OK;
return ret;
}
/****************************************************************************
@ -779,11 +785,10 @@ static void reply_spnego_negotiate(struct smb_request *req,
{
DATA_BLOB secblob;
DATA_BLOB chal;
bool got_kerberos_mechanism = False;
char *kerb_mech = NULL;
NTSTATUS status;
status = parse_spnego_mechanisms(blob1, &secblob,
&got_kerberos_mechanism);
status = parse_spnego_mechanisms(blob1, &secblob, &kerb_mech);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(vuid);
@ -795,16 +800,17 @@ static void reply_spnego_negotiate(struct smb_request *req,
(unsigned long)secblob.length));
#ifdef HAVE_KRB5
if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) ||
if (kerb_mech && ((lp_security()==SEC_ADS) ||
lp_use_kerberos_keytab()) ) {
bool destroy_vuid = True;
reply_spnego_kerberos(req, &secblob, vuid,
&destroy_vuid);
reply_spnego_kerberos(req, &secblob, kerb_mech,
vuid, &destroy_vuid);
data_blob_free(&secblob);
if (destroy_vuid) {
/* Kill the intermediate vuid */
invalidate_vuid(vuid);
}
SAFE_FREE(kerb_mech);
return;
}
#endif
@ -813,12 +819,12 @@ static void reply_spnego_negotiate(struct smb_request *req,
auth_ntlmssp_end(auth_ntlmssp_state);
}
if (got_kerberos_mechanism) {
if (kerb_mech) {
data_blob_free(&secblob);
/* The mechtoken is a krb5 ticket, but
* we need to fall back to NTLM. */
reply_spnego_downgrade_to_ntlmssp(req,
vuid);
reply_spnego_downgrade_to_ntlmssp(req, vuid);
SAFE_FREE(kerb_mech);
return;
}
@ -872,10 +878,9 @@ static void reply_spnego_auth(struct smb_request *req,
if (auth.data[0] == ASN1_APPLICATION(0)) {
/* Might be a second negTokenTarg packet */
char *kerb_mech = NULL;
bool got_krb5_mechanism = False;
status = parse_spnego_mechanisms(auth, &secblob,
&got_krb5_mechanism);
status = parse_spnego_mechanisms(auth, &secblob, &kerb_mech);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
@ -887,10 +892,10 @@ static void reply_spnego_auth(struct smb_request *req,
DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n",
(unsigned long)secblob.length));
#ifdef HAVE_KRB5
if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) ||
if (kerb_mech && ((lp_security()==SEC_ADS) ||
lp_use_kerberos_keytab()) ) {
bool destroy_vuid = True;
reply_spnego_kerberos(req, &secblob,
reply_spnego_kerberos(req, &secblob, kerb_mech,
vuid, &destroy_vuid);
data_blob_free(&secblob);
data_blob_free(&auth);
@ -898,13 +903,14 @@ static void reply_spnego_auth(struct smb_request *req,
/* Kill the intermediate vuid */
invalidate_vuid(vuid);
}
SAFE_FREE(kerb_mech);
return;
}
#endif
/* Can't blunder into NTLMSSP auth if we have
* a krb5 ticket. */
if (got_krb5_mechanism) {
if (kerb_mech) {
/* Kill the intermediate vuid */
invalidate_vuid(vuid);
DEBUG(3,("reply_spnego_auth: network "
@ -913,6 +919,7 @@ static void reply_spnego_auth(struct smb_request *req,
"not enabled"));
reply_nterror(req, nt_status_squash(
NT_STATUS_LOGON_FAILURE));
SAFE_FREE(kerb_mech);
}
}