/**************************************************************************** Old style search next. ****************************************************************************/ static NTSTATUS smb_raw_search_close_old(struct smbcli_tree *tree, union smb_search_close *io) { struct smbcli_request *req; uint8_t var_block[21]; req = smbcli_request_setup(tree, SMBfclose, 2, 0); if (!req) { return NT_STATUS_NO_MEMORY; } SSVAL(req->out.vwv, VWV(0), io->fclose.in.max_count); SSVAL(req->out.vwv, VWV(1), io->fclose.in.search_attrib); smbcli_req_append_ascii4(req, "", STR_TERMINATE); SCVAL(var_block, 0, io->fclose.in.id.reserved); memcpy(&var_block[1], io->fclose.in.id.name, 11); SCVAL(var_block, 12, io->fclose.in.id.handle); SIVAL(var_block, 13, io->fclose.in.id.server_cookie); SIVAL(var_block, 17, io->fclose.in.id.client_cookie); smbcli_req_append_var_block(req, var_block, 21); if (!smbcli_request_send(req) || !smbcli_request_receive(req)) { return smbcli_request_destroy(req); } return smbcli_request_destroy(req); }
/**************************************************************************** Close a file - async send ****************************************************************************/ _PUBLIC_ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms) { struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_CLOSE_CLOSE: SETUP_REQUEST(SMBclose, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->close.in.file.fnum); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->close.in.write_time); break; case RAW_CLOSE_SPLCLOSE: SETUP_REQUEST(SMBsplclose, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->splclose.in.file.fnum); SIVAL(req->out.vwv, VWV(1), 0); /* reserved */ break; case RAW_CLOSE_SMB2: case RAW_CLOSE_GENERIC: return NULL; } if (!req) return NULL; if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
static struct smbcli_request *smb_raw_openX_name_blob_send(struct smbcli_tree *tree, union smb_open *parms, const DATA_BLOB *pname_blob) { struct smbcli_request *req = NULL; if (parms->generic.level != RAW_OPEN_OPENX) { return NULL; } SETUP_REQUEST(SMBopenX, 15, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags); SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode); SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs); SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(6), parms->openx.in.write_time); SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func); SIVAL(req->out.vwv, VWV(9), parms->openx.in.size); SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout); SIVAL(req->out.vwv, VWV(13),0); /* reserved */ smbcli_req_append_blob(req, pname_blob); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/**************************************************************************** Rename a file - async interface ****************************************************************************/ struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree, union smb_rename *parms) { struct smbcli_request *req = NULL; struct smb_nttrans nt; TALLOC_CTX *mem_ctx; switch (parms->generic.level) { case RAW_RENAME_RENAME: SETUP_REQUEST(SMBmv, 1, 0); SSVAL(req->out.vwv, VWV(0), parms->rename.in.attrib); smbcli_req_append_ascii4(req, parms->rename.in.pattern1, STR_TERMINATE); smbcli_req_append_ascii4(req, parms->rename.in.pattern2, STR_TERMINATE); break; case RAW_RENAME_NTRENAME: SETUP_REQUEST(SMBntrename, 4, 0); SSVAL(req->out.vwv, VWV(0), parms->ntrename.in.attrib); SSVAL(req->out.vwv, VWV(1), parms->ntrename.in.flags); SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.cluster_size); smbcli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE); smbcli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE); break; case RAW_RENAME_NTTRANS: mem_ctx = talloc_new(tree); nt.in.max_setup = 0; nt.in.max_param = 0; nt.in.max_data = 0; nt.in.setup_count = 0; nt.in.setup = NULL; nt.in.function = NT_TRANSACT_RENAME; nt.in.params = data_blob_talloc(mem_ctx, NULL, 4); nt.in.data = data_blob(NULL, 0); SSVAL(nt.in.params.data, VWV(0), parms->nttrans.in.file.fnum); SSVAL(nt.in.params.data, VWV(1), parms->nttrans.in.flags); smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params, parms->nttrans.in.new_name, STR_TERMINATE); req = smb_raw_nttrans_send(tree, &nt); talloc_free(mem_ctx); return req; } if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/**************************************************************************** Send a exit (async send) *****************************************************************************/ struct smbcli_request *smb_raw_exit_send(struct smbcli_session *session) { struct smbcli_request *req; SETUP_REQUEST_SESSION(SMBexit, 0, 0); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/**************************************************************************** Query FS Info - SMBdskattr call (async send) ****************************************************************************/ static struct smbcli_request *smb_raw_dskattr_send(struct smbcli_tree *tree, union smb_fsinfo *fsinfo) { struct smbcli_request *req; req = smbcli_request_setup(tree, SMBdskattr, 0, 0); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/* scan for valid base SMB requests */ bool torture_smb_scan(struct torture_context *torture) { static struct smbcli_state *cli; int op; struct smbcli_request *req; NTSTATUS status; for (op=0x0;op<=0xFF;op++) { if (op == SMBreadbraw) continue; if (!torture_open_connection(&cli, torture, 0)) { return false; } req = smbcli_request_setup(cli->tree, op, 0, 0); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); break; } usleep(10000); smbcli_transport_process(cli->transport); if (req->state > SMBCLI_REQUEST_RECV) { status = smbcli_request_simple_recv(req); printf("op=0x%x status=%s\n", op, nt_errstr(status)); torture_close_connection(cli); continue; } sleep(1); smbcli_transport_process(cli->transport); if (req->state > SMBCLI_REQUEST_RECV) { status = smbcli_request_simple_recv(req); printf("op=0x%x status=%s\n", op, nt_errstr(status)); } else { printf("op=0x%x no reply\n", op); smbcli_request_destroy(req); continue; /* don't attempt close! */ } torture_close_connection(cli); } printf("smb scan finished\n"); return true; }
/* send a session request */ struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *transport, struct nbt_name *calling, struct nbt_name *called) { uint8_t *p; struct smbcli_request *req; DATA_BLOB calling_blob, called_blob; TALLOC_CTX *tmp_ctx = talloc_new(transport); NTSTATUS status; status = nbt_name_dup(transport, called, &transport->called); if (!NT_STATUS_IS_OK(status)) goto failed; status = nbt_name_to_blob(tmp_ctx, &calling_blob, calling); if (!NT_STATUS_IS_OK(status)) goto failed; status = nbt_name_to_blob(tmp_ctx, &called_blob, called); if (!NT_STATUS_IS_OK(status)) goto failed; /* allocate output buffer */ req = smbcli_request_setup_nonsmb(transport, NBT_HDR_SIZE + calling_blob.length + called_blob.length); if (req == NULL) goto failed; /* put in the destination name */ p = req->out.buffer + NBT_HDR_SIZE; memcpy(p, called_blob.data, called_blob.length); p += called_blob.length; memcpy(p, calling_blob.data, calling_blob.length); p += calling_blob.length; _smb_setlen(req->out.buffer, PTR_DIFF(p, req->out.buffer) - NBT_HDR_SIZE); SCVAL(req->out.buffer,0,0x81); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); goto failed; } talloc_free(tmp_ctx); return req; failed: talloc_free(tmp_ctx); return NULL; }
/**************************************************************************** Delete a file - async interface ****************************************************************************/ struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree, union smb_unlink *parms) { struct smbcli_request *req; SETUP_REQUEST(SMBunlink, 1, 0); SSVAL(req->out.vwv, VWV(0), parms->unlink.in.attrib); smbcli_req_append_ascii4(req, parms->unlink.in.pattern, STR_TERMINATE); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/**************************************************************************** Send a ulogoff (async send) *****************************************************************************/ struct smbcli_request *smb_raw_ulogoff_send(struct smbcli_session *session) { struct smbcli_request *req; SETUP_REQUEST_SESSION(SMBulogoffX, 2, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/**************************************************************************** Remove a directory - async interface ****************************************************************************/ struct smbcli_request *smb_raw_rmdir_send(struct smbcli_tree *tree, struct smb_rmdir *parms) { struct smbcli_request *req; SETUP_REQUEST(SMBrmdir, 0, 0); smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/**************************************************************************** Old style search next. ****************************************************************************/ static NTSTATUS smb_raw_search_next_old(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, void *private_data, smbcli_search_callback callback) { struct smbcli_request *req; uint8_t var_block[21]; uint8_t op = SMBsearch; if (io->generic.level == RAW_SEARCH_FFIRST) { op = SMBffirst; } req = smbcli_request_setup(tree, op, 2, 0); if (!req) { return NT_STATUS_NO_MEMORY; } SSVAL(req->out.vwv, VWV(0), io->search_next.in.max_count); SSVAL(req->out.vwv, VWV(1), io->search_next.in.search_attrib); smbcli_req_append_ascii4(req, "", STR_TERMINATE); SCVAL(var_block, 0, io->search_next.in.id.reserved); memcpy(&var_block[1], io->search_next.in.id.name, 11); SCVAL(var_block, 12, io->search_next.in.id.handle); SIVAL(var_block, 13, io->search_next.in.id.server_cookie); SIVAL(var_block, 17, io->search_next.in.id.client_cookie); smbcli_req_append_var_block(req, var_block, 21); if (!smbcli_request_send(req) || !smbcli_request_receive(req)) { return smbcli_request_destroy(req); } if (NT_STATUS_IS_OK(req->status)) { io->search_next.out.count = SVAL(req->in.vwv, VWV(0)); smb_raw_search_backend(req, mem_ctx, io->search_next.out.count, private_data, callback); } return smbcli_request_destroy(req); }
/**************************************************************************** Send an SMBecho (async send) *****************************************************************************/ _PUBLIC_ struct smbcli_request *smb_raw_echo_send(struct smbcli_transport *transport, struct smb_echo *p) { struct smbcli_request *req; req = smbcli_request_setup_transport(transport, SMBecho, 1, p->in.size); if (!req) return NULL; SSVAL(req->out.vwv, VWV(0), p->in.repeat_count); memcpy(req->out.data, p->in.data, p->in.size); ZERO_STRUCT(p->out); if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/* Send a negprot command. */ struct smbcli_request *smb_raw_negotiate_send(struct smbcli_transport *transport, bool unicode, int maxprotocol) { struct smbcli_request *req; int i; uint16_t flags2 = 0; req = smbcli_request_setup_transport(transport, SMBnegprot, 0, 0); if (!req) { return NULL; } flags2 |= FLAGS2_32_BIT_ERROR_CODES; if (unicode) { flags2 |= FLAGS2_UNICODE_STRINGS; } flags2 |= FLAGS2_EXTENDED_ATTRIBUTES; flags2 |= FLAGS2_LONG_PATH_COMPONENTS; flags2 |= FLAGS2_IS_LONG_NAME; if (transport->options.use_spnego) { flags2 |= FLAGS2_EXTENDED_SECURITY; } SSVAL(req->out.hdr,HDR_FLG2, flags2); /* setup the protocol strings */ for (i=0; i < ARRAY_SIZE(prots) && prots[i].prot <= maxprotocol; i++) { smbcli_req_append_bytes(req, (const uint8_t *)"\2", 1); smbcli_req_append_string(req, prots[i].name, STR_TERMINATE | STR_ASCII); } if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/* Implements trans2findclose2 */ NTSTATUS smb_raw_search_close(struct smbcli_tree *tree, union smb_search_close *io) { struct smbcli_request *req; if (io->generic.level == RAW_FINDCLOSE_FCLOSE) { return smb_raw_search_close_old(tree, io); } req = smbcli_request_setup(tree, SMBfindclose, 1, 0); if (!req) { return NT_STATUS_NO_MEMORY; } SSVAL(req->out.vwv, VWV(0), io->findclose.in.handle); if (smbcli_request_send(req)) { (void) smbcli_request_receive(req); } return smbcli_request_destroy(req); }
/**************************************************************************** Create a directory - async interface ****************************************************************************/ struct smbcli_request *smb_raw_mkdir_send(struct smbcli_tree *tree, union smb_mkdir *parms) { struct smbcli_request *req; if (parms->generic.level == RAW_MKDIR_T2MKDIR) { return smb_raw_t2mkdir_send(tree, parms); } if (parms->generic.level != RAW_MKDIR_MKDIR) { return NULL; } SETUP_REQUEST(SMBmkdir, 0, 0); smbcli_req_append_ascii4(req, parms->mkdir.in.path, STR_TERMINATE); if (!smbcli_request_send(req)) { return NULL; } return req; }
/**************************************************************************** Old style search first. ****************************************************************************/ static NTSTATUS smb_raw_search_first_old(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_first *io, void *private_data, smbcli_search_callback callback) { struct smbcli_request *req; uint8_t op = SMBsearch; if (io->generic.level == RAW_SEARCH_FFIRST) { op = SMBffirst; } else if (io->generic.level == RAW_SEARCH_FUNIQUE) { op = SMBfunique; } req = smbcli_request_setup(tree, op, 2, 0); if (!req) { return NT_STATUS_NO_MEMORY; } SSVAL(req->out.vwv, VWV(0), io->search_first.in.max_count); SSVAL(req->out.vwv, VWV(1), io->search_first.in.search_attrib); smbcli_req_append_ascii4(req, io->search_first.in.pattern, STR_TERMINATE); smbcli_req_append_var_block(req, NULL, 0); if (!smbcli_request_send(req) || !smbcli_request_receive(req)) { return smbcli_request_destroy(req); } if (NT_STATUS_IS_OK(req->status)) { io->search_first.out.count = SVAL(req->in.vwv, VWV(0)); smb_raw_search_backend(req, mem_ctx, io->search_first.out.count, private_data, callback); } return smbcli_request_destroy(req); }
/**************************************************************************** Open a file - async send ****************************************************************************/ _PUBLIC_ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms) { int len; struct smbcli_request *req = NULL; bool bigoffset = false; switch (parms->generic.level) { case RAW_OPEN_T2OPEN: return smb_raw_t2open_send(tree, parms); case RAW_OPEN_OPEN: SETUP_REQUEST(SMBopen, 2, 0); SSVAL(req->out.vwv, VWV(0), parms->openold.in.open_mode); SSVAL(req->out.vwv, VWV(1), parms->openold.in.search_attrs); smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE); break; case RAW_OPEN_OPENX: SETUP_REQUEST(SMBopenX, 15, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags); SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode); SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs); SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(6), parms->openx.in.write_time); SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func); SIVAL(req->out.vwv, VWV(9), parms->openx.in.size); SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout); SIVAL(req->out.vwv, VWV(13),0); /* reserved */ smbcli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE); break; case RAW_OPEN_MKNEW: SETUP_REQUEST(SMBmknew, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->mknew.in.write_time); smbcli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE); break; case RAW_OPEN_CREATE: SETUP_REQUEST(SMBcreate, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->create.in.attrib); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->create.in.write_time); smbcli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE); break; case RAW_OPEN_CTEMP: SETUP_REQUEST(SMBctemp, 3, 0); SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(1), parms->ctemp.in.write_time); smbcli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE); break; case RAW_OPEN_SPLOPEN: SETUP_REQUEST(SMBsplopen, 2, 0); SSVAL(req->out.vwv, VWV(0), parms->splopen.in.setup_length); SSVAL(req->out.vwv, VWV(1), parms->splopen.in.mode); break; case RAW_OPEN_NTCREATEX: SETUP_REQUEST(SMBntcreateX, 24, 0); SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1),0); SCVAL(req->out.vwv, VWV(2),0); /* padding */ SIVAL(req->out.vwv, 7, parms->ntcreatex.in.flags); SIVAL(req->out.vwv, 11, parms->ntcreatex.in.root_fid.fnum); SIVAL(req->out.vwv, 15, parms->ntcreatex.in.access_mask); SBVAL(req->out.vwv, 19, parms->ntcreatex.in.alloc_size); SIVAL(req->out.vwv, 27, parms->ntcreatex.in.file_attr); SIVAL(req->out.vwv, 31, parms->ntcreatex.in.share_access); SIVAL(req->out.vwv, 35, parms->ntcreatex.in.open_disposition); SIVAL(req->out.vwv, 39, parms->ntcreatex.in.create_options); SIVAL(req->out.vwv, 43, parms->ntcreatex.in.impersonation); SCVAL(req->out.vwv, 47, parms->ntcreatex.in.security_flags); smbcli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len); SSVAL(req->out.vwv, 5, len); break; case RAW_OPEN_NTTRANS_CREATE: return smb_raw_nttrans_create_send(tree, parms); case RAW_OPEN_OPENX_READX: SETUP_REQUEST(SMBopenX, 15, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->openxreadx.in.flags); SSVAL(req->out.vwv, VWV(3), parms->openxreadx.in.open_mode); SSVAL(req->out.vwv, VWV(4), parms->openxreadx.in.search_attrs); SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.file_attrs); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(6), parms->openxreadx.in.write_time); SSVAL(req->out.vwv, VWV(8), parms->openxreadx.in.open_func); SIVAL(req->out.vwv, VWV(9), parms->openxreadx.in.size); SIVAL(req->out.vwv, VWV(11),parms->openxreadx.in.timeout); SIVAL(req->out.vwv, VWV(13),0); smbcli_req_append_string(req, parms->openxreadx.in.fname, STR_TERMINATE); if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { bigoffset = true; } smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), 0); SIVAL(req->out.vwv, VWV(3), parms->openxreadx.in.offset); SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.maxcnt & 0xFFFF); SSVAL(req->out.vwv, VWV(6), parms->openxreadx.in.mincnt); SIVAL(req->out.vwv, VWV(7), parms->openxreadx.in.maxcnt >> 16); SSVAL(req->out.vwv, VWV(9), parms->openxreadx.in.remaining); if (bigoffset) { SIVAL(req->out.vwv, VWV(10),parms->openxreadx.in.offset>>32); } break; case RAW_OPEN_NTCREATEX_READX: SETUP_REQUEST(SMBntcreateX, 24, 0); SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1),0); SCVAL(req->out.vwv, VWV(2),0); /* padding */ SIVAL(req->out.vwv, 7, parms->ntcreatexreadx.in.flags); SIVAL(req->out.vwv, 11, parms->ntcreatexreadx.in.root_fid.fnum); SIVAL(req->out.vwv, 15, parms->ntcreatexreadx.in.access_mask); SBVAL(req->out.vwv, 19, parms->ntcreatexreadx.in.alloc_size); SIVAL(req->out.vwv, 27, parms->ntcreatexreadx.in.file_attr); SIVAL(req->out.vwv, 31, parms->ntcreatexreadx.in.share_access); SIVAL(req->out.vwv, 35, parms->ntcreatexreadx.in.open_disposition); SIVAL(req->out.vwv, 39, parms->ntcreatexreadx.in.create_options); SIVAL(req->out.vwv, 43, parms->ntcreatexreadx.in.impersonation); SCVAL(req->out.vwv, 47, parms->ntcreatexreadx.in.security_flags); smbcli_req_append_string_len(req, parms->ntcreatexreadx.in.fname, STR_TERMINATE, &len); SSVAL(req->out.vwv, 5, len); if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { bigoffset = true; } smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), 0); SIVAL(req->out.vwv, VWV(3), parms->ntcreatexreadx.in.offset); SSVAL(req->out.vwv, VWV(5), parms->ntcreatexreadx.in.maxcnt & 0xFFFF); SSVAL(req->out.vwv, VWV(6), parms->ntcreatexreadx.in.mincnt); SIVAL(req->out.vwv, VWV(7), parms->ntcreatexreadx.in.maxcnt >> 16); SSVAL(req->out.vwv, VWV(9), parms->ntcreatexreadx.in.remaining); if (bigoffset) { SIVAL(req->out.vwv, VWV(10),parms->ntcreatexreadx.in.offset>>32); } break; case RAW_OPEN_SMB2: return NULL; } if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/**************************************************************************** low level read operation (async send) ****************************************************************************/ _PUBLIC_ struct smbcli_request *smb_raw_read_send(struct smbcli_tree *tree, union smb_read *parms) { bool bigoffset = false; struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_READ_READBRAW: if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { bigoffset = true; } SETUP_REQUEST(SMBreadbraw, bigoffset? 10:8, 0); SSVAL(req->out.vwv, VWV(0), parms->readbraw.in.file.fnum); SIVAL(req->out.vwv, VWV(1), parms->readbraw.in.offset); SSVAL(req->out.vwv, VWV(3), parms->readbraw.in.maxcnt); SSVAL(req->out.vwv, VWV(4), parms->readbraw.in.mincnt); SIVAL(req->out.vwv, VWV(5), parms->readbraw.in.timeout); SSVAL(req->out.vwv, VWV(7), 0); /* reserved */ if (bigoffset) { SIVAL(req->out.vwv, VWV(8),parms->readbraw.in.offset>>32); } break; case RAW_READ_LOCKREAD: SETUP_REQUEST(SMBlockread, 5, 0); SSVAL(req->out.vwv, VWV(0), parms->lockread.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->lockread.in.count); SIVAL(req->out.vwv, VWV(2), parms->lockread.in.offset); SSVAL(req->out.vwv, VWV(4), parms->lockread.in.remaining); break; case RAW_READ_READ: SETUP_REQUEST(SMBread, 5, 0); SSVAL(req->out.vwv, VWV(0), parms->read.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->read.in.count); SIVAL(req->out.vwv, VWV(2), parms->read.in.offset); SSVAL(req->out.vwv, VWV(4), parms->read.in.remaining); break; case RAW_READ_READX: if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { bigoffset = true; } SETUP_REQUEST(SMBreadX, bigoffset ? 12 : 10, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->readx.in.file.fnum); SIVAL(req->out.vwv, VWV(3), parms->readx.in.offset); SSVAL(req->out.vwv, VWV(5), parms->readx.in.maxcnt & 0xFFFF); SSVAL(req->out.vwv, VWV(6), parms->readx.in.mincnt); SIVAL(req->out.vwv, VWV(7), parms->readx.in.maxcnt >> 16); SSVAL(req->out.vwv, VWV(9), parms->readx.in.remaining); /* * TODO: give an error when the offset is 64 bit * and the server doesn't support it */ if (bigoffset) { SIVAL(req->out.vwv, VWV(10),parms->readx.in.offset>>32); } if (parms->readx.in.read_for_execute) { uint16_t flags2 = SVAL(req->out.hdr, HDR_FLG2); flags2 |= FLAGS2_READ_PERMIT_EXECUTE; SSVAL(req->out.hdr, HDR_FLG2, flags2); } break; case RAW_READ_SMB2: return NULL; } if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } /* the transport layer needs to know that a readbraw is pending and handle receives a little differently */ if (parms->generic.level == RAW_READ_READBRAW) { tree->session->transport->readbraw_pending = 1; } return req; }
/**************************************************************************** Perform a session setup (async send) ****************************************************************************/ struct smbcli_request *smb_raw_sesssetup_send(struct smbcli_session *session, union smb_sesssetup *parms) { struct smbcli_request *req = NULL; switch (parms->old.level) { case RAW_SESSSETUP_OLD: SETUP_REQUEST_SESSION(SMBsesssetupX, 10, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv,VWV(2),parms->old.in.bufsize); SSVAL(req->out.vwv,VWV(3),parms->old.in.mpx_max); SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num); SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey); SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length); SIVAL(req->out.vwv,VWV(8), 0); /* reserved */ smbcli_req_append_blob(req, &parms->old.in.password); smbcli_req_append_string(req, parms->old.in.user, STR_TERMINATE); smbcli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER); smbcli_req_append_string(req, parms->old.in.os, STR_TERMINATE); smbcli_req_append_string(req, parms->old.in.lanman, STR_TERMINATE); break; case RAW_SESSSETUP_NT1: SETUP_REQUEST_SESSION(SMBsesssetupX, 13, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->nt1.in.bufsize); SSVAL(req->out.vwv, VWV(3), parms->nt1.in.mpx_max); SSVAL(req->out.vwv, VWV(4), parms->nt1.in.vc_num); SIVAL(req->out.vwv, VWV(5), parms->nt1.in.sesskey); SSVAL(req->out.vwv, VWV(7), parms->nt1.in.password1.length); SSVAL(req->out.vwv, VWV(8), parms->nt1.in.password2.length); SIVAL(req->out.vwv, VWV(9), 0); /* reserved */ SIVAL(req->out.vwv, VWV(11), parms->nt1.in.capabilities); smbcli_req_append_blob(req, &parms->nt1.in.password1); smbcli_req_append_blob(req, &parms->nt1.in.password2); smbcli_req_append_string(req, parms->nt1.in.user, STR_TERMINATE); smbcli_req_append_string(req, parms->nt1.in.domain, STR_TERMINATE|STR_UPPER); smbcli_req_append_string(req, parms->nt1.in.os, STR_TERMINATE); smbcli_req_append_string(req, parms->nt1.in.lanman, STR_TERMINATE); break; case RAW_SESSSETUP_SPNEGO: SETUP_REQUEST_SESSION(SMBsesssetupX, 12, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->spnego.in.bufsize); SSVAL(req->out.vwv, VWV(3), parms->spnego.in.mpx_max); SSVAL(req->out.vwv, VWV(4), parms->spnego.in.vc_num); SIVAL(req->out.vwv, VWV(5), parms->spnego.in.sesskey); SSVAL(req->out.vwv, VWV(7), parms->spnego.in.secblob.length); SIVAL(req->out.vwv, VWV(8), 0); /* reserved */ SIVAL(req->out.vwv, VWV(10), parms->spnego.in.capabilities); smbcli_req_append_blob(req, &parms->spnego.in.secblob); smbcli_req_append_string(req, parms->spnego.in.os, STR_TERMINATE); smbcli_req_append_string(req, parms->spnego.in.lanman, STR_TERMINATE); smbcli_req_append_string(req, parms->spnego.in.workgroup, STR_TERMINATE); break; case RAW_SESSSETUP_SMB2: return NULL; } if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }
/**************************************************************************** raw write interface (async send) ****************************************************************************/ _PUBLIC_ struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_write *parms) { bool bigoffset = false; struct smbcli_request *req = NULL; switch (parms->generic.level) { case RAW_WRITE_WRITEUNLOCK: SETUP_REQUEST(SMBwriteunlock, 5, 3 + parms->writeunlock.in.count); SSVAL(req->out.vwv, VWV(0), parms->writeunlock.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->writeunlock.in.count); SIVAL(req->out.vwv, VWV(2), parms->writeunlock.in.offset); SSVAL(req->out.vwv, VWV(4), parms->writeunlock.in.remaining); SCVAL(req->out.data, 0, SMB_DATA_BLOCK); SSVAL(req->out.data, 1, parms->writeunlock.in.count); if (parms->writeunlock.in.count > 0) { memcpy(req->out.data+3, parms->writeunlock.in.data, parms->writeunlock.in.count); } break; case RAW_WRITE_WRITE: SETUP_REQUEST(SMBwrite, 5, 3 + parms->write.in.count); SSVAL(req->out.vwv, VWV(0), parms->write.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->write.in.count); SIVAL(req->out.vwv, VWV(2), parms->write.in.offset); SSVAL(req->out.vwv, VWV(4), parms->write.in.remaining); SCVAL(req->out.data, 0, SMB_DATA_BLOCK); SSVAL(req->out.data, 1, parms->write.in.count); if (parms->write.in.count > 0) { memcpy(req->out.data+3, parms->write.in.data, parms->write.in.count); } break; case RAW_WRITE_WRITECLOSE: SETUP_REQUEST(SMBwriteclose, 6, 1 + parms->writeclose.in.count); SSVAL(req->out.vwv, VWV(0), parms->writeclose.in.file.fnum); SSVAL(req->out.vwv, VWV(1), parms->writeclose.in.count); SIVAL(req->out.vwv, VWV(2), parms->writeclose.in.offset); raw_push_dos_date3(tree->session->transport, req->out.vwv, VWV(4), parms->writeclose.in.mtime); SCVAL(req->out.data, 0, 0); if (parms->writeclose.in.count > 0) { memcpy(req->out.data+1, parms->writeclose.in.data, parms->writeclose.in.count); } break; case RAW_WRITE_WRITEX: if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) { bigoffset = true; } SETUP_REQUEST(SMBwriteX, bigoffset ? 14 : 12, parms->writex.in.count); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); SSVAL(req->out.vwv, VWV(2), parms->writex.in.file.fnum); SIVAL(req->out.vwv, VWV(3), parms->writex.in.offset); SIVAL(req->out.vwv, VWV(5), 0); /* reserved */ SSVAL(req->out.vwv, VWV(7), parms->writex.in.wmode); SSVAL(req->out.vwv, VWV(8), parms->writex.in.remaining); SSVAL(req->out.vwv, VWV(9), parms->writex.in.count>>16); SSVAL(req->out.vwv, VWV(10), parms->writex.in.count); SSVAL(req->out.vwv, VWV(11), PTR_DIFF(req->out.data, req->out.hdr)); if (bigoffset) { SIVAL(req->out.vwv,VWV(12),parms->writex.in.offset>>32); } if (parms->writex.in.count > 0) { memcpy(req->out.data, parms->writex.in.data, parms->writex.in.count); } break; case RAW_WRITE_SPLWRITE: SETUP_REQUEST(SMBsplwr, 1, parms->splwrite.in.count); SSVAL(req->out.vwv, VWV(0), parms->splwrite.in.file.fnum); if (parms->splwrite.in.count > 0) { memcpy(req->out.data, parms->splwrite.in.data, parms->splwrite.in.count); } break; case RAW_WRITE_SMB2: return NULL; } if (!smbcli_request_send(req)) { smbcli_request_destroy(req); return NULL; } return req; }