/* push a string in a uint16_t ofs/ uint16_t length/blob format UTF-16 without termination */ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, uint16_t ofs, const char *str) { DATA_BLOB blob; NTSTATUS status; bool ret; void *ptr = NULL; if (str == NULL) { return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } if (*str == 0) { blob.data = discard_const_p(uint8_t, str); blob.length = 0; return smb2_push_o16s16_blob(buf, ofs, blob); } ret = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, str, strlen(str), &ptr, &blob.length); if (!ret) { return NT_STATUS_ILLEGAL_CHARACTER; } blob.data = (uint8_t *)ptr; status = smb2_push_o16s16_blob(buf, ofs, blob); data_blob_free(&blob); return status; }
/** send a session setup request */ struct smb2_request *smb2_session_setup_send(struct smb2_session *session, struct smb2_session_setup *io) { struct smb2_request *req; NTSTATUS status; req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, 0x18, true, io->in.secblob.length); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, session->uid); SCVAL(req->out.body, 0x02, io->in.vc_number); SCVAL(req->out.body, 0x03, io->in.security_mode); SIVAL(req->out.body, 0x04, io->in.capabilities); SIVAL(req->out.body, 0x08, io->in.channel); SBVAL(req->out.body, 0x10, io->in.previous_sessionid); req->session = session; status = smb2_push_o16s16_blob(&req->out, 0x0C, io->in.secblob); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; } smb2_transport_send(req); return req; }
/* push a string in a uint16_t ofs/ uint16_t length/blob format UTF-16 without termination */ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, uint16_t ofs, const char *str) { DATA_BLOB blob; NTSTATUS status; ssize_t size; if (strcmp("", str) == 0) { return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } size = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, str, strlen(str), (void **)&blob.data); if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; } blob.length = size; status = smb2_push_o16s16_blob(buf, ofs, blob); data_blob_free(&blob); return status; }
static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io) { if (NT_STATUS_IS_OK(req->status)) { /* nothing */ } else if (NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { /* nothing */ } else { smb2srv_send_error(req, req->status); return; } SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, true, io->smb2.out.secblob.length)); SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, io->smb2.out.uid); SSVAL(req->out.body, 0x02, io->smb2.out.session_flags); SMB2SRV_CHECK(smb2_push_o16s16_blob(&req->out, 0x04, io->smb2.out.secblob)); smb2srv_send_reply(req); }
static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negprot *io) { NTSTATUS status; if (NT_STATUS_IS_ERR(req->status)) { smb2srv_send_error(req, req->status); /* TODO: is this correct? */ return; } status = smb2srv_setup_reply(req, 0x40, true, io->out.secblob.length); if (!NT_STATUS_IS_OK(status)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); talloc_free(req); return; } SSVAL(req->out.body, 0x02, io->out.security_mode); SIVAL(req->out.body, 0x04, io->out.dialect_revision); SIVAL(req->out.body, 0x06, io->out.reserved); status = smbcli_push_guid(req->out.body, 0x08, &io->out.server_guid); if (!NT_STATUS_IS_OK(status)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); talloc_free(req); return; } SIVAL(req->out.body, 0x18, io->out.capabilities); SIVAL(req->out.body, 0x1C, io->out.max_transact_size); SIVAL(req->out.body, 0x20, io->out.max_read_size); SIVAL(req->out.body, 0x24, io->out.max_write_size); push_nttime(req->out.body, 0x28, io->out.system_time); push_nttime(req->out.body, 0x30, io->out.server_start_time); SIVAL(req->out.body, 0x3C, io->out.reserved2); status = smb2_push_o16s16_blob(&req->out, 0x38, io->out.secblob); if (!NT_STATUS_IS_OK(status)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); talloc_free(req); return; } smb2srv_send_reply(req); }
static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io) { uint16_t unknown1; if (NT_STATUS_IS_OK(req->status)) { unknown1 = 0x0003; } else if (NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { unknown1 = 0x0002; } else { smb2srv_send_error(req, req->status); return; } SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, True, io->smb2.out.secblob.length)); SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1, unknown1); SBVAL(req->out.hdr, SMB2_HDR_UID, io->smb2.out.uid); SSVAL(req->out.body, 0x02, io->smb2.out._pad); SMB2SRV_CHECK(smb2_push_o16s16_blob(&req->out, 0x04, io->smb2.out.secblob)); smb2srv_send_reply(req); }
static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negprot *io) { NTSTATUS status; if (NT_STATUS_IS_ERR(req->status)) { smb2srv_send_error(req, req->status); /* TODO: is this correct? */ return; } status = smb2srv_setup_reply(req, 0x40, True, io->out.secblob.length); if (!NT_STATUS_IS_OK(status)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); talloc_free(req); return; } SSVAL(req->out.body, 0x02, io->out._pad); SIVAL(req->out.body, 0x04, io->out.unknown2); memcpy(req->out.body+0x08, io->out.sessid, 16); SIVAL(req->out.body, 0x18, io->out.unknown3); SSVAL(req->out.body, 0x1C, io->out.unknown4); SIVAL(req->out.body, 0x1E, io->out.unknown5); SIVAL(req->out.body, 0x22, io->out.unknown6); SSVAL(req->out.body, 0x26, io->out.unknown7); push_nttime(req->out.body, 0x28, io->out.current_time); push_nttime(req->out.body, 0x30, io->out.boot_time); status = smb2_push_o16s16_blob(&req->out, 0x38, io->out.secblob); if (!NT_STATUS_IS_OK(status)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); talloc_free(req); return; } SIVAL(req->out.body, 0x3C, io->out.unknown9); smb2srv_send_reply(req); }