1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-28 01:58:17 +03:00

s3-auth use auth_generic_start to get full GENSEC in Samba3 session setup

This tests if the auth_generic_start() hook is available on the auth
context during the negprot, and if so it uses auth_generic_start() to
hook to GENSEC to handle the full SPNEGO blob.

Andrew Bartlett

Signed-off-by: Andrew Tridgell <tridge@samba.org>
This commit is contained in:
Andrew Bartlett 2011-07-26 15:11:47 +10:00
parent 9f663270fd
commit d3524f2eae
4 changed files with 83 additions and 33 deletions

View File

@ -474,6 +474,9 @@ struct smbd_server_connection {
unsigned long file_gen_counter;
int first_file;
/* Try GENSEC hook */
bool use_gensec_hook;
/* number of open connections (tcons) */
int num_tcons_open;

View File

@ -24,8 +24,10 @@
#include "../libcli/auth/spnego.h"
#include "serverid.h"
#include "auth.h"
#include "ntlmssp_wrap.h"
#include "messages.h"
#include "smbprofile.h"
#include "auth/gensec/gensec.h"
extern fstring remote_proto;
@ -187,6 +189,7 @@ DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn)
DATA_BLOB blob_out = data_blob_null;
nstring dos_name;
fstring unix_name;
NTSTATUS status;
#ifdef DEVELOPER
size_t slen;
#endif
@ -195,8 +198,29 @@ DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn)
OID_NTLMSSP,
NULL};
const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
struct auth_ntlmssp_state *auth_ntlmssp_state;
sconn->use_gensec_hook = false;
/* See if we can get an SPNEGO blob out of the gensec hook (if auth_samba4 is loaded) */
status = auth_ntlmssp_prepare(sconn->remote_address,
&auth_ntlmssp_state);
if (NT_STATUS_IS_OK(status)) {
status = auth_generic_start(auth_ntlmssp_state, GENSEC_OID_SPNEGO);
if (NT_STATUS_IS_OK(status)) {
status = auth_ntlmssp_update(auth_ntlmssp_state, ctx,
data_blob_null, &blob);
/* If we get the list of OIDs, the 'OK' answer
* is NT_STATUS_MORE_PROCESSING_REQUIRED */
if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
sconn->use_gensec_hook = true;
}
}
TALLOC_FREE(auth_ntlmssp_state);
}
sconn->smb1.negprot.spnego = true;
/* strangely enough, NT does not sent the single OID NTLMSSP when
not a ADS member, it sends no OIDs at all
@ -210,7 +234,9 @@ DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn)
*/
if (lp_security() != SEC_ADS && !USE_KERBEROS_KEYTAB) {
if (sconn->use_gensec_hook) {
/* blob initialised above */
} else if (lp_security() != SEC_ADS && !USE_KERBEROS_KEYTAB) {
#if 0
/* Code for PocketPC client */
blob = data_blob(guid, 16);

View File

@ -36,6 +36,7 @@
#include "messages.h"
#include "smbprofile.h"
#include "../libcli/security/security.h"
#include "auth/gensec/gensec.h"
/* For split krb5 SPNEGO blobs. */
struct pending_auth_data {
@ -1134,27 +1135,12 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
return;
}
if (blob1.data[0] == ASN1_APPLICATION(0)) {
/* its a negTokenTarg packet */
reply_spnego_negotiate(req, vuid, blob1,
&vuser->auth_ntlmssp_state);
data_blob_free(&blob1);
return;
}
if (blob1.data[0] == ASN1_CONTEXT(1)) {
/* its a auth packet */
reply_spnego_auth(req, vuid, blob1,
&vuser->auth_ntlmssp_state);
data_blob_free(&blob1);
return;
}
if (blob1.length > 7 && strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
/* Handle either raw NTLMSSP or hand off the whole blob to
* GENSEC. The processing at this layer is essentially
* identical regardless. In particular, both rely only on the
* status code (not the contents of the packet) and do not
* wrap the result */
if (sconn->use_gensec_hook || (blob1.length > 7 && strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0)) {
DATA_BLOB chal;
if (!vuser->auth_ntlmssp_state) {
@ -1170,7 +1156,11 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
auth_ntlmssp_want_feature(vuser->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
status = auth_ntlmssp_start(vuser->auth_ntlmssp_state);
if (sconn->use_gensec_hook) {
status = auth_generic_start(vuser->auth_ntlmssp_state, GENSEC_OID_SPNEGO);
} else {
status = auth_ntlmssp_start(vuser->auth_ntlmssp_state);
}
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(sconn, vuid);
@ -1193,6 +1183,26 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
return;
}
if (blob1.data[0] == ASN1_APPLICATION(0)) {
/* its a negTokenTarg packet */
reply_spnego_negotiate(req, vuid, blob1,
&vuser->auth_ntlmssp_state);
data_blob_free(&blob1);
return;
}
if (blob1.data[0] == ASN1_CONTEXT(1)) {
/* its a auth packet */
reply_spnego_auth(req, vuid, blob1,
&vuser->auth_ntlmssp_state);
data_blob_free(&blob1);
return;
}
/* what sort of packet is this? */
DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));

View File

@ -25,6 +25,7 @@
#include "../libcli/smb/smb_common.h"
#include "../libcli/auth/spnego.h"
#include "../libcli/auth/ntlmssp.h"
#include "../auth/gensec/gensec.h"
#include "ntlmssp_wrap.h"
#include "../librpc/gen_ndr/krb5pac.h"
#include "libads/kerberos_proto.h"
@ -649,7 +650,11 @@ static NTSTATUS smbd_smb2_raw_ntlmssp_auth(struct smbd_smb2_session *session,
auth_ntlmssp_want_feature(session->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
status = auth_ntlmssp_start(session->auth_ntlmssp_state);
if (session->sconn->use_gensec_hook) {
status = auth_generic_start(session->auth_ntlmssp_state, GENSEC_OID_SPNEGO);
} else {
status = auth_ntlmssp_start(session->auth_ntlmssp_state);
}
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(session);
return status;
@ -742,7 +747,21 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
return NT_STATUS_REQUEST_NOT_ACCEPTED;
}
if (in_security_buffer.data[0] == ASN1_APPLICATION(0)) {
/* Handle either raw NTLMSSP or hand off the whole blob to
* GENSEC. The processing at this layer is essentially
* identical regardless. In particular, both rely only on the
* status code (not the contents of the packet) and do not
* wrap the result */
if (session->sconn->use_gensec_hook
|| (in_security_buffer.length > 7 && strncmp((char *)(in_security_buffer.data), "NTLMSSP", 7) == 0)) {
return smbd_smb2_raw_ntlmssp_auth(session,
smb2req,
in_security_mode,
in_security_buffer,
out_session_flags,
out_security_buffer,
out_session_id);
} else if (in_security_buffer.data[0] == ASN1_APPLICATION(0)) {
return smbd_smb2_spnego_negotiate(session,
smb2req,
in_security_mode,
@ -758,14 +777,6 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
out_session_flags,
out_security_buffer,
out_session_id);
} else if (in_security_buffer.length > 7 && strncmp((char *)(in_security_buffer.data), "NTLMSSP", 7) == 0) {
return smbd_smb2_raw_ntlmssp_auth(session,
smb2req,
in_security_mode,
in_security_buffer,
out_session_flags,
out_security_buffer,
out_session_id);
}
/* Unknown packet type. */