#include "includes.h"
#include "smbd/globals.h"
-#include "../source4/libcli/smb2/smb2_constants.h"
+#include "../libcli/smb/smb_common.h"
+#include "../libcli/auth/spnego.h"
static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
uint64_t in_session_id,
outdyn = out_security_buffer;
- return smbd_smb2_request_done_ex(req, status, outbody, &outdyn);
+ return smbd_smb2_request_done_ex(req, status, outbody, &outdyn,
+ __location__);
}
static int smbd_smb2_session_destructor(struct smbd_smb2_session *session)
{
- if (session->conn == NULL) {
+ if (session->sconn == NULL) {
return 0;
}
talloc_free(session->tcons.list);
}
- idr_remove(session->conn->smb2.sessions.idtree, session->vuid);
- DLIST_REMOVE(session->conn->smb2.sessions.list, session);
+ idr_remove(session->sconn->smb2.sessions.idtree, session->vuid);
+ DLIST_REMOVE(session->sconn->smb2.sessions.list, session);
+ invalidate_vuid(session->sconn, session->vuid);
session->vuid = 0;
session->status = NT_STATUS_USER_SESSION_DELETED;
- session->conn = NULL;
+ session->sconn = NULL;
return 0;
}
NTSTATUS status;
*out_session_flags = 0;
+ *out_session_id = 0;
if (in_session_id == 0) {
int id;
/* create a new session */
- session = talloc_zero(req->conn, struct smbd_smb2_session);
+ session = talloc_zero(req->sconn, struct smbd_smb2_session);
if (session == NULL) {
return NT_STATUS_NO_MEMORY;
}
session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
- id = idr_get_new_random(req->conn->smb2.sessions.idtree,
+ id = idr_get_new_random(req->sconn->smb2.sessions.idtree,
session,
- req->conn->smb2.sessions.limit);
+ req->sconn->smb2.sessions.limit);
if (id == -1) {
return NT_STATUS_INSUFFICIENT_RESOURCES;
}
if (session->tcons.idtree == NULL) {
return NT_STATUS_NO_MEMORY;
}
- session->tcons.limit = 0x00FFFFFF;
+ session->tcons.limit = 0x0000FFFE;
session->tcons.list = NULL;
- DLIST_ADD_END(req->conn->smb2.sessions.list, session,
+ DLIST_ADD_END(req->sconn->smb2.sessions.list, session,
struct smbd_smb2_session *);
- session->conn = req->conn;
+ session->sconn = req->sconn;
talloc_set_destructor(session, smbd_smb2_session_destructor);
} else {
void *p;
/* lookup an existing session */
- p = idr_find(req->conn->smb2.sessions.idtree, in_session_id);
+ p = idr_find(req->sconn->smb2.sessions.idtree, in_session_id);
if (p == NULL) {
return NT_STATUS_USER_SESSION_DELETED;
}
}
}
- status = auth_ntlmssp_update(session->auth_ntlmssp_state,
- in_security_buffer,
- out_security_buffer);
- if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ if (in_security_buffer.data[0] == ASN1_APPLICATION(0)) {
+ DATA_BLOB secblob_in;
+ DATA_BLOB chal_out;
+ char *kerb_mech = NULL;
+
+ status = parse_spnego_mechanisms(in_security_buffer,
+ &secblob_in, &kerb_mech);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(session);
+ return nt_status_squash(status);
+ }
+
+ /* For now, just SPNEGO NTLMSSP - krb5 goes here later.. */
+ status = auth_ntlmssp_update(session->auth_ntlmssp_state,
+ secblob_in,
+ &chal_out);
+
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ auth_ntlmssp_end(&session->auth_ntlmssp_state);
+ TALLOC_FREE(session);
+ return nt_status_squash(status);
+ }
+
+ *out_security_buffer = spnego_gen_auth_response(&chal_out,
+ status, OID_NTLMSSP);
+
*out_session_id = session->vuid;
return status;
- } else if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(session);
- return status;
+ } else if (in_security_buffer.data[0] == ASN1_CONTEXT(1)) {
+ DATA_BLOB auth = data_blob_null;
+ DATA_BLOB auth_out = data_blob_null;
+
+ /* its an auth packet */
+ if (!spnego_parse_auth(in_security_buffer, &auth)) {
+ TALLOC_FREE(session);
+ return NT_STATUS_LOGON_FAILURE;
+ }
+ /* For now, just SPNEGO NTLMSSP - krb5 goes here later.. */
+ status = auth_ntlmssp_update(session->auth_ntlmssp_state,
+ auth,
+ &auth_out);
+ if (!NT_STATUS_IS_OK(status)) {
+ auth_ntlmssp_end(&session->auth_ntlmssp_state);
+ TALLOC_FREE(session);
+ return nt_status_squash(status);
+ }
+
+ *out_security_buffer = spnego_gen_auth_response(&auth_out,
+ status, NULL);
+
+ *out_session_id = session->vuid;
+ } else if (strncmp((char *)(in_security_buffer.data), "NTLMSSP", 7) == 0) {
+
+ /* RAW NTLMSSP */
+ status = auth_ntlmssp_update(session->auth_ntlmssp_state,
+ in_security_buffer,
+ out_security_buffer);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ *out_session_id = session->vuid;
+ return status;
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ auth_ntlmssp_end(&session->auth_ntlmssp_state);
+ TALLOC_FREE(session);
+ return nt_status_squash(status);
+ }
+ *out_session_id = session->vuid;
}
/* TODO: setup session key for signing */
session->compat_vuser->server_info = session->server_info;
session->compat_vuser->session_keystr = NULL;
session->compat_vuser->vuid = session->vuid;
- DLIST_ADD(session->conn->smb1.sessions.validated_users, session->compat_vuser);
+ DLIST_ADD(session->sconn->smb1.sessions.validated_users, session->compat_vuser);
session->status = NT_STATUS_OK;
in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
/* lookup an existing session */
- p = idr_find(req->conn->smb2.sessions.idtree, in_session_id);
+ p = idr_find(req->sconn->smb2.sessions.idtree, in_session_id);
if (p == NULL) {
return NT_STATUS_USER_SESSION_DELETED;
}