This helps map on to the GENSEC semantics better, and ensures that the
full set of desired features are set before the mechanism starts.
Andrew Bartlett
Signed-off-by: Andrew Tridgell <tridge@samba.org>
static int auth_ntlmssp_state_destructor(void *ptr);
static int auth_ntlmssp_state_destructor(void *ptr);
-NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address,
- struct auth_ntlmssp_state **auth_ntlmssp_state)
+NTSTATUS auth_ntlmssp_prepare(const struct tsocket_address *remote_address,
+ struct auth_ntlmssp_state **auth_ntlmssp_state)
{
NTSTATUS nt_status;
bool is_standalone;
{
NTSTATUS nt_status;
bool is_standalone;
+ ans->auth_context = talloc_steal(ans, auth_context);
+
if (auth_context->prepare_gensec) {
nt_status = auth_context->prepare_gensec(ans, &ans->gensec_security);
if (!NT_STATUS_IS_OK(nt_status)) {
TALLOC_FREE(ans);
return nt_status;
} else {
if (auth_context->prepare_gensec) {
nt_status = auth_context->prepare_gensec(ans, &ans->gensec_security);
if (!NT_STATUS_IS_OK(nt_status)) {
TALLOC_FREE(ans);
return nt_status;
} else {
- nt_status = auth_context->gensec_start_mech_by_oid(ans->gensec_security, GENSEC_OID_NTLMSSP);
- if (!NT_STATUS_IS_OK(nt_status)) {
- TALLOC_FREE(ans);
- return nt_status;
- } else {
- *auth_ntlmssp_state = ans;
- return NT_STATUS_OK;
- }
+ *auth_ntlmssp_state = ans;
+ return NT_STATUS_OK;
- ans->auth_context = talloc_steal(ans, auth_context);
-
ans->ntlmssp_state->callback_private = ans;
ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
ans->ntlmssp_state->callback_private = ans;
ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
TALLOC_FREE(ans->ntlmssp_state);
return 0;
}
TALLOC_FREE(ans->ntlmssp_state);
return 0;
}
+
+NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state *auth_ntlmssp_state)
+{
+ if (auth_ntlmssp_state->auth_context->gensec_start_mech_by_oid) {
+ return auth_ntlmssp_state->auth_context->gensec_start_mech_by_oid(auth_ntlmssp_state->gensec_security, GENSEC_OID_NTLMSSP);
+ }
+
+ return NT_STATUS_OK;
+}
NTSTATUS auth_ntlmssp_steal_session_info(TALLOC_CTX *mem_ctx,
struct auth_ntlmssp_state *auth_ntlmssp_state,
struct auth_session_info **session_info);
NTSTATUS auth_ntlmssp_steal_session_info(TALLOC_CTX *mem_ctx,
struct auth_ntlmssp_state *auth_ntlmssp_state,
struct auth_session_info **session_info);
-NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address,
+NTSTATUS auth_ntlmssp_prepare(const struct tsocket_address *remote_address,
struct auth_ntlmssp_state **auth_ntlmssp_state);
struct auth_ntlmssp_state **auth_ntlmssp_state);
+NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state *auth_ntlmssp_state);
/* The following definitions come from auth/auth_sam.c */
/* The following definitions come from auth/auth_sam.c */
struct auth_ntlmssp_state *a = NULL;
NTSTATUS status;
struct auth_ntlmssp_state *a = NULL;
NTSTATUS status;
- status = auth_ntlmssp_start(remote_address, &a);
+ status = auth_ntlmssp_prepare(remote_address, &a);
if (!NT_STATUS_IS_OK(status)) {
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, (__location__ ": auth_ntlmssp_start failed: %s\n",
+ DEBUG(0, (__location__ ": auth_ntlmssp_prepare failed: %s\n",
nt_errstr(status)));
return status;
}
nt_errstr(status)));
return status;
}
auth_ntlmssp_want_feature(a, NTLMSSP_FEATURE_SEAL);
}
auth_ntlmssp_want_feature(a, NTLMSSP_FEATURE_SEAL);
}
+ status = auth_ntlmssp_start(a);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, (__location__ ": auth_ntlmssp_start failed: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
status = auth_ntlmssp_update(a, mem_ctx, *token_in, token_out);
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
DEBUG(0, (__location__ ": auth_ntlmssp_update failed: %s\n",
status = auth_ntlmssp_update(a, mem_ctx, *token_in, token_out);
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
DEBUG(0, (__location__ ": auth_ntlmssp_update failed: %s\n",
static NTSTATUS make_auth_ntlmssp(const struct tsocket_address *remote_address,
struct smb_srv_trans_enc_ctx *ec)
{
static NTSTATUS make_auth_ntlmssp(const struct tsocket_address *remote_address,
struct smb_srv_trans_enc_ctx *ec)
{
- NTSTATUS status = auth_ntlmssp_start(remote_address,
+ NTSTATUS status = auth_ntlmssp_prepare(remote_address,
&ec->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
return nt_status_squash(status);
&ec->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
return nt_status_squash(status);
auth_ntlmssp_want_feature(ec->auth_ntlmssp_state, NTLMSSP_FEATURE_SEAL);
auth_ntlmssp_want_feature(ec->auth_ntlmssp_state, NTLMSSP_FEATURE_SEAL);
+ status = auth_ntlmssp_start(ec->auth_ntlmssp_state);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return nt_status_squash(status);
+ }
+
/*
* We must remember to update the pointer copy for the common
* functions after any auth_ntlmssp_start/auth_ntlmssp_end.
/*
* We must remember to update the pointer copy for the common
* functions after any auth_ntlmssp_start/auth_ntlmssp_end.
- status = auth_ntlmssp_start(sconn->remote_address,
- auth_ntlmssp_state);
+ status = auth_ntlmssp_prepare(sconn->remote_address,
+ auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(sconn, vuid);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(sconn, vuid);
auth_ntlmssp_want_feature(*auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
auth_ntlmssp_want_feature(*auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+ status = auth_ntlmssp_start(*auth_ntlmssp_state);
+ if (!NT_STATUS_IS_OK(status)) {
+ /* Kill the intermediate vuid */
+ invalidate_vuid(sconn, vuid);
+ reply_nterror(req, nt_status_squash(status));
+ return;
+ }
+
status = auth_ntlmssp_update(*auth_ntlmssp_state, talloc_tos(),
secblob, &chal);
status = auth_ntlmssp_update(*auth_ntlmssp_state, talloc_tos(),
secblob, &chal);
data_blob_free(&secblob);
if (!*auth_ntlmssp_state) {
data_blob_free(&secblob);
if (!*auth_ntlmssp_state) {
- status = auth_ntlmssp_start(sconn->remote_address,
- auth_ntlmssp_state);
+ status = auth_ntlmssp_prepare(sconn->remote_address,
+ auth_ntlmssp_state);
+ if (!NT_STATUS_IS_OK(status)) {
+ /* Kill the intermediate vuid */
+ invalidate_vuid(sconn, vuid);
+ reply_nterror(req, nt_status_squash(status));
+ return;
+ }
+
+ auth_ntlmssp_want_feature(*auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+
+ status = auth_ntlmssp_start(*auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(sconn, vuid);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(sconn, vuid);
DATA_BLOB chal;
if (!vuser->auth_ntlmssp_state) {
DATA_BLOB chal;
if (!vuser->auth_ntlmssp_state) {
- status = auth_ntlmssp_start(sconn->remote_address,
- &vuser->auth_ntlmssp_state);
+ status = auth_ntlmssp_prepare(sconn->remote_address,
+ &vuser->auth_ntlmssp_state);
+ if (!NT_STATUS_IS_OK(status)) {
+ /* Kill the intermediate vuid */
+ invalidate_vuid(sconn, vuid);
+ data_blob_free(&blob1);
+ reply_nterror(req, nt_status_squash(status));
+ return;
+ }
+
+ auth_ntlmssp_want_feature(vuser->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+
+ status = auth_ntlmssp_start(vuser->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(sconn, vuid);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
invalidate_vuid(sconn, vuid);
status = NT_STATUS_MORE_PROCESSING_REQUIRED;
} else {
/* Fall back to NTLMSSP. */
status = NT_STATUS_MORE_PROCESSING_REQUIRED;
} else {
/* Fall back to NTLMSSP. */
- status = auth_ntlmssp_start(session->sconn->remote_address,
+ status = auth_ntlmssp_prepare(session->sconn->remote_address,
&session->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
goto out;
&session->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
goto out;
auth_ntlmssp_want_feature(session->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
auth_ntlmssp_want_feature(session->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+ status = auth_ntlmssp_start(session->auth_ntlmssp_state);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
status = auth_ntlmssp_update(session->auth_ntlmssp_state,
talloc_tos(),
secblob_in,
status = auth_ntlmssp_update(session->auth_ntlmssp_state,
talloc_tos(),
secblob_in,
}
if (session->auth_ntlmssp_state == NULL) {
}
if (session->auth_ntlmssp_state == NULL) {
- status = auth_ntlmssp_start(session->sconn->remote_address,
+ status = auth_ntlmssp_prepare(session->sconn->remote_address,
&session->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
data_blob_free(&auth);
TALLOC_FREE(session);
return status;
}
&session->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
data_blob_free(&auth);
TALLOC_FREE(session);
return status;
}
+
+ auth_ntlmssp_want_feature(session->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+
+ status = auth_ntlmssp_start(session->auth_ntlmssp_state);
+ if (!NT_STATUS_IS_OK(status)) {
+ data_blob_free(&auth);
+ TALLOC_FREE(session);
+ return status;
+ }
}
status = auth_ntlmssp_update(session->auth_ntlmssp_state,
}
status = auth_ntlmssp_update(session->auth_ntlmssp_state,
NTSTATUS status;
if (session->auth_ntlmssp_state == NULL) {
NTSTATUS status;
if (session->auth_ntlmssp_state == NULL) {
- status = auth_ntlmssp_start(session->sconn->remote_address,
+ status = auth_ntlmssp_prepare(session->sconn->remote_address,
&session->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(session);
return status;
}
&session->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(session);
return status;
}
+
+ auth_ntlmssp_want_feature(session->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+
+ status = auth_ntlmssp_start(session->auth_ntlmssp_state);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(session);
+ return status;
+ }