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:
parent
9f663270fd
commit
d3524f2eae
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"));
|
||||
|
||||
|
@ -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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user