From ccc27e681cbd6283513b929d58f2ebce35e6658b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 12:54:44 +1100 Subject: fixed up the .in side of SMB2 negprot fixed the input side of the SMB2 negprot structure and parsers according to the documentation (This used to be commit 55af8acc7b32c24e4b1187e9d8d1c8f060e914b0) --- source4/smb_server/smb/negprot.c | 1 + source4/smb_server/smb2/negprot.c | 40 ++++++++++++++++++++++++++++++++++----- source4/smb_server/smb_server.h | 2 +- 3 files changed, 37 insertions(+), 6 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index 6d9ff838cb..b57e5e1d64 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -466,6 +466,7 @@ static const struct { void (*proto_reply_fn)(struct smbsrv_request *req, uint16_t choice); int protocol_level; } supported_protocols[] = { + {"SMB 2.002", "SMB2", reply_smb2, PROTOCOL_SMB2}, {"SMB 2.001", "SMB2", reply_smb2, PROTOCOL_SMB2}, {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1}, {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1}, diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 8e3cfd3547..68509d71c6 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -21,6 +21,7 @@ #include "includes.h" #include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" +#include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" #include "smb_server/smb_server.h" @@ -92,6 +93,12 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 struct timeval current_time; struct timeval boot_time; + /* we only do dialect 0 for now */ + if (io->in.dialect_count < 1 || + io->in.dialects[0] != 0) { + return NT_STATUS_NOT_SUPPORTED; + } + req->smb_conn->negotiate.protocol = PROTOCOL_SMB2; current_time = timeval_current(); /* TODO: handle timezone?! */ @@ -155,6 +162,9 @@ static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negpro void smb2srv_negprot_recv(struct smb2srv_request *req) { struct smb2_negprot *io; + int i; + DATA_BLOB guid_blob; + enum ndr_err_code ndr_err; if (req->in.body_size < 0x26) { smb2srv_send_error(req, NT_STATUS_FOOBAR); @@ -168,9 +178,30 @@ void smb2srv_negprot_recv(struct smb2srv_request *req) return; } - io->in.unknown1 = SVAL(req->in.body, 0x02); - memcpy(io->in.unknown2, req->in.body + 0x04, 0x20); - io->in.unknown3 = SVAL(req->in.body, 0x24); + io->in.dialect_count = SVAL(req->in.body, 0x02); + io->in.security_mode = SVAL(req->in.body, 0x04); + io->in.reserved = SVAL(req->in.body, 0x06); + io->in.capabilities = IVAL(req->in.body, 0x08); + guid_blob.data = req->in.body + 0xC; + guid_blob.length = 16; + ndr_err = ndr_pull_struct_blob(&guid_blob, req, NULL, &io->in.client_guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_FOOBAR)); + talloc_free(req); + return; + } + io->in.start_time = smbcli_pull_nttime(req->in.body, 0x1C); + + io->in.dialects = talloc_array(req, uint16_t, io->in.dialect_count); + if (io->in.dialects == NULL) { + smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY)); + talloc_free(req); + return; + } + for (i=0;iin.dialect_count;i++) { + io->in.dialects[i] = SVAL(req->in.body, 0x24+i*2); + } req->status = smb2srv_negprot_backend(req, io); @@ -182,14 +213,13 @@ void smb2srv_negprot_recv(struct smb2srv_request *req) } /* - * reply to a SMB negprot request with dialect "SMB 2.001" + * reply to a SMB negprot request with dialect "SMB 2.002" */ void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req) { struct smb2srv_request *req; uint32_t body_fixed_size = 0x26; - /* create a fake SMB2 negprot request */ req = talloc_zero(smb_req->smb_conn, struct smb2srv_request); if (!req) goto nomem; req->smb_conn = smb_req->smb_conn; diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h index 5644dfe6fb..bb0673b7d0 100644 --- a/source4/smb_server/smb_server.h +++ b/source4/smb_server/smb_server.h @@ -291,7 +291,7 @@ struct smbsrv_connection { /* the negotiatiated protocol */ enum protocol_types protocol; - + /* authentication context for multi-part negprot */ struct auth_context *auth_context; -- cgit From 8fdb9504dcfc98080c5c2b5ce134b51ab631fa95 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 16:20:13 +1100 Subject: converted the out side of SMB2 negprot handling This follows the SMB2 PFIF docs. Current versions of Vista can now connect to Samba4 as a SMB2 server and do basic operations (This used to be commit 9dc284770df9393a1a619735dc7a148713936fa7) --- source4/smb_server/smb2/negprot.c | 59 ++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 29 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 68509d71c6..043534d777 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -96,7 +96,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 /* we only do dialect 0 for now */ if (io->in.dialect_count < 1 || io->in.dialects[0] != 0) { - return NT_STATUS_NOT_SUPPORTED; + DEBUG(0,("Got unexpected SMB2 dialect %u\n", io->in.dialects[0])); } req->smb_conn->negotiate.protocol = PROTOCOL_SMB2; @@ -104,19 +104,19 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 current_time = timeval_current(); /* TODO: handle timezone?! */ boot_time = timeval_current(); /* TODO: fix me */ - io->out._pad = 0; - io->out.unknown2 = 0x06; - ZERO_STRUCT(io->out.sessid); - io->out.unknown3 = 0x0d; - io->out.unknown4 = 0x00; - io->out.unknown5 = 0x01; - io->out.unknown6 = 0x01; - io->out.unknown7 = 0x01; - io->out.current_time = timeval_to_nttime(¤t_time); - io->out.boot_time = timeval_to_nttime(&boot_time); + ZERO_STRUCT(io->out); + io->out.security_mode = 0; /* no signing yet */ + /* choose the first dialect offered for now */ + io->out.dialect_revision = io->in.dialects[0]; + io->out.capabilities = 0; + io->out.max_transact_size = 0x10000; + io->out.max_read_size = 0x10000; + io->out.max_write_size = 0x10000; + io->out.system_time = timeval_to_nttime(¤t_time); + io->out.server_start_time = timeval_to_nttime(&boot_time); + io->out.reserved2 = 0; status = smb2srv_negprot_secblob(req, &io->out.secblob); NT_STATUS_NOT_OK_RETURN(status); - io->out.unknown9 = 0x204d4c20; return NT_STATUS_OK; } @@ -124,6 +124,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negprot *io) { NTSTATUS status; + enum ndr_err_code ndr_err; if (NT_STATUS_IS_ERR(req->status)) { smb2srv_send_error(req, req->status); /* TODO: is this correct? */ @@ -137,16 +138,22 @@ static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negpro 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); + 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); + ndr_err = smbcli_push_guid(req->out.body, 0x08, &io->out.server_guid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + 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)); @@ -154,8 +161,6 @@ static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negpro return; } - SIVAL(req->out.body, 0x3C, io->out.unknown9); - smb2srv_send_reply(req); } @@ -163,7 +168,6 @@ void smb2srv_negprot_recv(struct smb2srv_request *req) { struct smb2_negprot *io; int i; - DATA_BLOB guid_blob; enum ndr_err_code ndr_err; if (req->in.body_size < 0x26) { @@ -182,10 +186,7 @@ void smb2srv_negprot_recv(struct smb2srv_request *req) io->in.security_mode = SVAL(req->in.body, 0x04); io->in.reserved = SVAL(req->in.body, 0x06); io->in.capabilities = IVAL(req->in.body, 0x08); - guid_blob.data = req->in.body + 0xC; - guid_blob.length = 16; - ndr_err = ndr_pull_struct_blob(&guid_blob, req, NULL, &io->in.client_guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); + ndr_err = smbcli_pull_guid(req->in.body, 0xC, &io->in.client_guid); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_FOOBAR)); talloc_free(req); -- cgit From 416360895f36d41ce8d29c25ef08e2b8b4e38571 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 16:43:38 +1100 Subject: converted SMB2 session setup to use WSPP protocol field names (This used to be commit 3c2af0fdc4916dce32c2690e49dde0852d1a0c50) --- source4/smb_server/smb2/sesssetup.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/sesssetup.c b/source4/smb_server/smb2/sesssetup.c index 636f5f0e27..b4c78a2ebd 100644 --- a/source4/smb_server/smb2/sesssetup.c +++ b/source4/smb_server/smb2/sesssetup.c @@ -48,7 +48,7 @@ static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sessse 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); + 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); @@ -108,7 +108,7 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses struct smbsrv_session *smb_sess = NULL; uint64_t vuid; - io->smb2.out._pad = 0; + io->smb2.out.session_flags = 0; io->smb2.out.uid = 0; io->smb2.out.secblob = data_blob(NULL, 0); @@ -192,12 +192,13 @@ void smb2srv_sesssetup_recv(struct smb2srv_request *req) SMB2SRV_CHECK_BODY_SIZE(req, 0x18, true); SMB2SRV_TALLOC_IO_PTR(io, union smb_sesssetup); - io->smb2.level = RAW_SESSSETUP_SMB2; - io->smb2.in._pad = SVAL(req->in.body, 0x02); - io->smb2.in.unknown2 = IVAL(req->in.body, 0x04); - io->smb2.in.unknown3 = IVAL(req->in.body, 0x08); + io->smb2.level = RAW_SESSSETUP_SMB2; + io->smb2.in.vc_number = CVAL(req->in.body, 0x02); + io->smb2.in.security_mode = CVAL(req->in.body, 0x03); + io->smb2.in.capabilities = IVAL(req->in.body, 0x04); + io->smb2.in.channel = IVAL(req->in.body, 0x08); + io->smb2.in.previous_sessionid = BVAL(req->in.body, 0x10); SMB2SRV_CHECK(smb2_pull_o16s16_blob(&req->in, io, req->in.body+0x0C, &io->smb2.in.secblob)); - io->smb2.in.unknown4 = BVAL(req->in.body, 0x10); smb2srv_sesssetup_backend(req, io); } -- cgit From a2505c5a2cc2b7b692ffbcdd8c6b86000a15d2c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 17:00:35 +1100 Subject: updated SMB2 header defines to match WSPP docs (This used to be commit d2c6ad55eca27f50a38fc6e2a85032eddb3f0aae) --- source4/smb_server/smb2/negprot.c | 12 ++++++------ source4/smb_server/smb2/receive.c | 18 +++++++++--------- source4/smb_server/smb2/sesssetup.c | 12 ++++++------ source4/smb_server/smb2/tcon.c | 22 +++++++++++----------- 4 files changed, 32 insertions(+), 32 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 043534d777..4f44147606 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -238,17 +238,17 @@ void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req) SIVAL(req->in.hdr, 0, SMB2_MAGIC); SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); - SSVAL(req->in.hdr, SMB2_HDR_PAD1, 0); + SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0); SIVAL(req->in.hdr, SMB2_HDR_STATUS, 0); SSVAL(req->in.hdr, SMB2_HDR_OPCODE, SMB2_OP_NEGPROT); - SSVAL(req->in.hdr, SMB2_HDR_UNKNOWN1, 0); + SSVAL(req->in.hdr, SMB2_HDR_CREDIT, 0); SIVAL(req->in.hdr, SMB2_HDR_FLAGS, 0); - SIVAL(req->in.hdr, SMB2_HDR_CHAIN_OFFSET, 0); - SBVAL(req->in.hdr, SMB2_HDR_SEQNUM, 0); + SIVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND, 0); + SBVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID, 0); SIVAL(req->in.hdr, SMB2_HDR_PID, 0); SIVAL(req->in.hdr, SMB2_HDR_TID, 0); - SBVAL(req->in.hdr, SMB2_HDR_UID, 0); - memset(req->in.hdr+SMB2_HDR_SIG, 0, 16); + SBVAL(req->in.hdr, SMB2_HDR_SESSION_ID, 0); + memset(req->in.hdr+SMB2_HDR_SIGNATURE, 0, 16); /* this seems to be a bug, they use 0x24 but the length is 0x26 */ SSVAL(req->in.body, 0x00, 0x24); diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c index cfae2dbe52..393b3f0cc5 100644 --- a/source4/smb_server/smb2/receive.c +++ b/source4/smb_server/smb2/receive.c @@ -94,17 +94,17 @@ NTSTATUS smb2srv_setup_reply(struct smb2srv_request *req, uint16_t body_fixed_si SIVAL(req->out.hdr, 0, SMB2_MAGIC); SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); - SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); + SSVAL(req->out.hdr, SMB2_HDR_EPOCH, 0); SIVAL(req->out.hdr, SMB2_HDR_STATUS, NT_STATUS_V(req->status)); SSVAL(req->out.hdr, SMB2_HDR_OPCODE, SVAL(req->in.hdr, SMB2_HDR_OPCODE)); - SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1, 0x0001); + SSVAL(req->out.hdr, SMB2_HDR_CREDIT, 0x0001); SIVAL(req->out.hdr, SMB2_HDR_FLAGS, flags); - SIVAL(req->out.hdr, SMB2_HDR_CHAIN_OFFSET, 0); - SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); + SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND, 0); + SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID, req->seqnum); SIVAL(req->out.hdr, SMB2_HDR_PID, pid); SIVAL(req->out.hdr, SMB2_HDR_TID, tid); - SBVAL(req->out.hdr, SMB2_HDR_UID, BVAL(req->in.hdr, SMB2_HDR_UID)); - memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); + SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, BVAL(req->in.hdr, SMB2_HDR_SESSION_ID)); + memset(req->out.hdr+SMB2_HDR_SIGNATURE, 0, 16); /* set the length of the fixed body part and +1 if there's a dynamic part also */ SSVAL(req->out.body, 0, body_fixed_size + (body_dynamic_size?1:0)); @@ -259,10 +259,10 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req) uint64_t uid; opcode = SVAL(req->in.hdr, SMB2_HDR_OPCODE); - req->chain_offset = IVAL(req->in.hdr, SMB2_HDR_CHAIN_OFFSET); - req->seqnum = BVAL(req->in.hdr, SMB2_HDR_SEQNUM); + req->chain_offset = IVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND); + req->seqnum = BVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID); tid = IVAL(req->in.hdr, SMB2_HDR_TID); - uid = BVAL(req->in.hdr, SMB2_HDR_UID); + uid = BVAL(req->in.hdr, SMB2_HDR_SESSION_ID); req->session = smbsrv_session_find(req->smb_conn, uid, req->request_time); req->tcon = smbsrv_smb2_tcon_find(req->session, tid, req->request_time); diff --git a/source4/smb_server/smb2/sesssetup.c b/source4/smb_server/smb2/sesssetup.c index b4c78a2ebd..1aaacf897c 100644 --- a/source4/smb_server/smb2/sesssetup.c +++ b/source4/smb_server/smb2/sesssetup.c @@ -32,12 +32,12 @@ static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io) { - uint16_t unknown1; + uint16_t credit; if (NT_STATUS_IS_OK(req->status)) { - unknown1 = 0x0003; + credit = 0x0003; } else if (NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - unknown1 = 0x0002; + credit = 0x0002; } else { smb2srv_send_error(req, req->status); return; @@ -45,8 +45,8 @@ static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sessse 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.hdr, SMB2_HDR_CREDIT, credit); + 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)); @@ -112,7 +112,7 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses io->smb2.out.uid = 0; io->smb2.out.secblob = data_blob(NULL, 0); - vuid = BVAL(req->in.hdr, SMB2_HDR_UID); + vuid = BVAL(req->in.hdr, SMB2_HDR_SESSION_ID); /* * only when we got '0' we should allocate a new session diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c index 6d0d98554c..824a57b4a1 100644 --- a/source4/smb_server/smb2/tcon.c +++ b/source4/smb_server/smb2/tcon.c @@ -57,24 +57,24 @@ static NTSTATUS smb2srv_send_oplock_break(void *p, struct ntvfs_handle *h, uint8 SIVAL(req->in.hdr, 0, SMB2_MAGIC); SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); - SSVAL(req->in.hdr, SMB2_HDR_PAD1, 0); + SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0); SIVAL(req->in.hdr, SMB2_HDR_STATUS, 0); SSVAL(req->in.hdr, SMB2_HDR_OPCODE, SMB2_OP_BREAK); - SSVAL(req->in.hdr, SMB2_HDR_UNKNOWN1, 0); + SSVAL(req->in.hdr, SMB2_HDR_CREDIT, 0); SIVAL(req->in.hdr, SMB2_HDR_FLAGS, 0); - SIVAL(req->in.hdr, SMB2_HDR_CHAIN_OFFSET, 0); - SBVAL(req->in.hdr, SMB2_HDR_SEQNUM, 0); + SIVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND, 0); + SBVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID, 0); SIVAL(req->in.hdr, SMB2_HDR_PID, 0); SIVAL(req->in.hdr, SMB2_HDR_TID, 0); - SBVAL(req->in.hdr, SMB2_HDR_UID, 0); - memset(req->in.hdr+SMB2_HDR_SIG, 0, 16); + SBVAL(req->in.hdr, SMB2_HDR_SESSION_ID, 0); + memset(req->in.hdr+SMB2_HDR_SIGNATURE, 0, 16); SSVAL(req->in.body, 0, 2); status = smb2srv_setup_reply(req, 0x18, false, 0); NT_STATUS_NOT_OK_RETURN(status); - SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1, 0x0000); + SSVAL(req->out.hdr, SMB2_HDR_CREDIT, 0x0000); SSVAL(req->out.body, 0x02, 0x0001); SIVAL(req->out.body, 0x04, 0x00000000); @@ -361,7 +361,7 @@ failed: static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io) { - uint16_t unknown1; + uint16_t credit; if (!NT_STATUS_IS_OK(req->status)) { smb2srv_send_error(req, req->status); @@ -369,15 +369,15 @@ static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io) } if (io->smb2.out.unknown1 == 0x0002) { /* if it's an IPC share vista returns 0x0005 */ - unknown1 = 0x0005; + credit = 0x0005; } else { - unknown1 = 0x0001; + credit = 0x0001; } SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x10, false, 0)); SIVAL(req->out.hdr, SMB2_HDR_TID, io->smb2.out.tid); - SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1,unknown1); + SSVAL(req->out.hdr, SMB2_HDR_CREDIT,credit); SSVAL(req->out.body, 0x02, io->smb2.out.unknown1); SIVAL(req->out.body, 0x04, io->smb2.out.unknown2); -- cgit From cd2b003abaaaed5054db6e266dbfccf7e1193932 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 20:29:31 +1100 Subject: fixed crash when 0 dialects (thanks metze!) (This used to be commit 252bcf207b8117f325075cbb7bd05063756ac283) --- source4/smb_server/smb2/negprot.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 4f44147606..7c295c05ab 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -94,8 +94,10 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 struct timeval boot_time; /* we only do dialect 0 for now */ - if (io->in.dialect_count < 1 || - io->in.dialects[0] != 0) { + if (io->in.dialect_count < 1) { + return NT_STATUS_NOT_SUPPORTED; + } + if (io->in.dialects[0] != 0) { DEBUG(0,("Got unexpected SMB2 dialect %u\n", io->in.dialects[0])); } -- cgit From e94d710b0b959d8e69eb02ef0704ebcff56485fb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Feb 2008 10:13:28 +1100 Subject: updated SMB2 tcon as per WSPP docs (This used to be commit 5913e3e549e71affc66c28cacb6563331fb0c790) --- source4/smb_server/smb2/tcon.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c index 824a57b4a1..b375ce6b4b 100644 --- a/source4/smb_server/smb2/tcon.c +++ b/source4/smb_server/smb2/tcon.c @@ -240,8 +240,6 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon struct smbsrv_tcon *tcon; NTSTATUS status; enum ntvfs_type type; - uint16_t type_smb2; - uint32_t unknown2; const char *service = io->smb2.in.path; struct share_config *scfg; const char *sharetype; @@ -270,16 +268,10 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon sharetype = share_string_option(scfg, SHARE_TYPE, "DISK"); if (sharetype && strcmp(sharetype, "IPC") == 0) { type = NTVFS_IPC; - type_smb2 = 0x0002; - unknown2 = 0x00000030; } else if (sharetype && strcmp(sharetype, "PRINTER") == 0) { type = NTVFS_PRINT; - type_smb2 = 0x0003; - unknown2 = 0x00000000; } else { type = NTVFS_DISK; - type_smb2 = 0x0001; - unknown2 = 0x00000800; } tcon = smbsrv_smb2_tcon_new(req->session, scfg->name); @@ -344,10 +336,11 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon goto failed; } - io->smb2.out.unknown1 = type_smb2; /* 1 - DISK, 2 - Print, 3 - IPC */ - io->smb2.out.unknown2 = unknown2; - io->smb2.out.unknown3 = 0x00000000; - io->smb2.out.access_mask= SEC_RIGHTS_FILE_ALL; + io->smb2.out.share_type = (unsigned)type; /* 1 - DISK, 2 - Print, 3 - IPC */ + io->smb2.out.reserved = 0; + io->smb2.out.flags = 0x00000000; + io->smb2.out.capabilities = 0; + io->smb2.out.access_mask = SEC_RIGHTS_FILE_ALL; io->smb2.out.tid = tcon->tid; @@ -367,7 +360,7 @@ static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io) smb2srv_send_error(req, req->status); return; } - if (io->smb2.out.unknown1 == 0x0002) { + if (io->smb2.out.share_type == NTVFS_IPC) { /* if it's an IPC share vista returns 0x0005 */ credit = 0x0005; } else { @@ -379,9 +372,10 @@ static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io) SIVAL(req->out.hdr, SMB2_HDR_TID, io->smb2.out.tid); SSVAL(req->out.hdr, SMB2_HDR_CREDIT,credit); - SSVAL(req->out.body, 0x02, io->smb2.out.unknown1); - SIVAL(req->out.body, 0x04, io->smb2.out.unknown2); - SIVAL(req->out.body, 0x08, io->smb2.out.unknown3); + SCVAL(req->out.body, 0x02, io->smb2.out.share_type); + SCVAL(req->out.body, 0x03, io->smb2.out.reserved); + SIVAL(req->out.body, 0x04, io->smb2.out.flags); + SIVAL(req->out.body, 0x08, io->smb2.out.capabilities); SIVAL(req->out.body, 0x0C, io->smb2.out.access_mask); smb2srv_send_reply(req); @@ -395,7 +389,7 @@ void smb2srv_tcon_recv(struct smb2srv_request *req) SMB2SRV_TALLOC_IO_PTR(io, union smb_tcon); io->smb2.level = RAW_TCON_SMB2; - io->smb2.in.unknown1 = SVAL(req->in.body, 0x02); + io->smb2.in.reserved = SVAL(req->in.body, 0x02); SMB2SRV_CHECK(smb2_pull_o16s16_string(&req->in, io, req->in.body+0x04, &io->smb2.in.path)); req->status = smb2srv_tcon_backend(req, io); -- cgit From 88d2e0522737fb8856fb0f52c2af8a2f56130f19 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Feb 2008 15:05:44 +1100 Subject: updated SMB2 create operation to match WSPP. Adding some defined for various new create options (This used to be commit d037dc23ced3df6bce98cbf4810fb5f1247336bd) --- source4/smb_server/smb2/fileio.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/fileio.c b/source4/smb_server/smb2/fileio.c index 0e83c78615..567243ba94 100644 --- a/source4/smb_server/smb2/fileio.c +++ b/source4/smb_server/smb2/fileio.c @@ -34,7 +34,8 @@ static void smb2srv_create_send(struct ntvfs_request *ntvfs) SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_open); SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x58, true, io->smb2.out.blob.length)); - SSVAL(req->out.body, 0x02, io->smb2.out.oplock_flags); + SCVAL(req->out.body, 0x02, io->smb2.out.oplock_level); + SCVAL(req->out.body, 0x03, io->smb2.out.reserved); SIVAL(req->out.body, 0x04, io->smb2.out.create_action); SBVAL(req->out.body, 0x08, io->smb2.out.create_time); SBVAL(req->out.body, 0x10, io->smb2.out.access_time); @@ -43,7 +44,7 @@ static void smb2srv_create_send(struct ntvfs_request *ntvfs) SBVAL(req->out.body, 0x28, io->smb2.out.alloc_size); SBVAL(req->out.body, 0x30, io->smb2.out.size); SIVAL(req->out.body, 0x38, io->smb2.out.file_attr); - SIVAL(req->out.body, 0x3C, io->smb2.out._pad); + SIVAL(req->out.body, 0x3C, io->smb2.out.reserved2); smb2srv_push_handle(req->out.body, 0x40, io->smb2.out.file.ntvfs); SMB2SRV_CHECK(smb2_push_o32s32_blob(&req->out, 0x50, io->smb2.out.blob)); @@ -64,16 +65,15 @@ void smb2srv_create_recv(struct smb2srv_request *req) SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_create_send, NTVFS_ASYNC_STATE_MAY_ASYNC); io->smb2.level = RAW_OPEN_SMB2; - io->smb2.in.oplock_flags = SVAL(req->in.body, 0x02); - io->smb2.in.impersonation = IVAL(req->in.body, 0x04); - io->smb2.in.unknown3[0] = IVAL(req->in.body, 0x08); - io->smb2.in.unknown3[1] = IVAL(req->in.body, 0x0C); - io->smb2.in.unknown3[2] = IVAL(req->in.body, 0x10); - io->smb2.in.unknown3[3] = IVAL(req->in.body, 0x14); - io->smb2.in.access_mask = IVAL(req->in.body, 0x18); - io->smb2.in.file_attr = IVAL(req->in.body, 0x1C); + io->smb2.in.security_flags = CVAL(req->in.body, 0x02); + io->smb2.in.oplock_level = CVAL(req->in.body, 0x03); + io->smb2.in.impersonation_level = IVAL(req->in.body, 0x04); + io->smb2.in.create_flags = BVAL(req->in.body, 0x08); + io->smb2.in.reserved = BVAL(req->in.body, 0x10); + io->smb2.in.desired_access = IVAL(req->in.body, 0x18); + io->smb2.in.file_attributes = IVAL(req->in.body, 0x1C); io->smb2.in.share_access = IVAL(req->in.body, 0x20); - io->smb2.in.open_disposition = IVAL(req->in.body, 0x24); + io->smb2.in.create_disposition = IVAL(req->in.body, 0x24); io->smb2.in.create_options = IVAL(req->in.body, 0x28); SMB2SRV_CHECK(smb2_pull_o16s16_string(&req->in, io, req->in.body+0x2C, &io->smb2.in.fname)); SMB2SRV_CHECK(smb2_pull_o32s32_blob(&req->in, io, req->in.body+0x30, &blob)); -- cgit From e870cfec9f3512b0f1bd3110d7b975652525e28a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 10:12:33 +1100 Subject: Convert SMB and SMB2 code to use a common buffer handling structure This converts our SMB and SMB2 code to use a common structure "struct request_bufinfo" for information on the buffer bounds of a packet, alignment information and string handling. This allows us to use a common backend for SMB and SMB2 code, while still using all the same string and blob handling functions. Up to now we had been passing a NULL req handle into these common routines from the SMB2 side of the server, which meant that we failed any operation which did a bounds checked string extraction (such as a RenameInformation setinfo call, which is what Vista uses for renaming files) There is still some more work to be done on this - for example we can now remove many of the SMB2 specific buffer handling functions that we had, and use the SMB ones. (This used to be commit ca6d9be6cb6a403a81b18fa6e9a6a0518d7f0f68) --- source4/smb_server/blob.c | 16 +++---- source4/smb_server/smb/negprot.c | 2 +- source4/smb_server/smb/nttrans.c | 6 +-- source4/smb_server/smb/receive.c | 6 +++ source4/smb_server/smb/reply.c | 94 +++++++++++++++++++------------------- source4/smb_server/smb/request.c | 61 +++++++++++++++---------- source4/smb_server/smb/search.c | 12 ++--- source4/smb_server/smb/trans2.c | 24 +++++----- source4/smb_server/smb2/fileinfo.c | 2 +- source4/smb_server/smb2/negprot.c | 2 + source4/smb_server/smb2/receive.c | 20 ++++++++ source4/smb_server/smb2/tcon.c | 2 + source4/smb_server/smb_server.h | 4 +- 13 files changed, 144 insertions(+), 107 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/blob.c b/source4/smb_server/blob.c index 2b870118ba..caf6fb447d 100644 --- a/source4/smb_server/blob.c +++ b/source4/smb_server/blob.c @@ -78,7 +78,7 @@ NTSTATUS smbsrv_blob_fill_data(TALLOC_CTX *mem_ctx, /* pull a string from a blob in a trans2 request */ -size_t smbsrv_blob_pull_string(struct smbsrv_request *req, +size_t smbsrv_blob_pull_string(struct request_bufinfo *bufinfo, const DATA_BLOB *blob, uint16_t offset, const char **str, @@ -92,7 +92,7 @@ size_t smbsrv_blob_pull_string(struct smbsrv_request *req, return 0; } - return req_pull_string(req, str, + return req_pull_string(bufinfo, str, blob->data + offset, blob->length - offset, STR_NO_RANGE_CHECK | flags); @@ -521,7 +521,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, union smb_setfileinfo *st, const DATA_BLOB *blob, int default_str_flags, - struct smbsrv_request *req) + struct request_bufinfo *bufinfo) { uint32_t len; DATA_BLOB str_blob; @@ -560,12 +560,8 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; case RAW_SFILEINFO_RENAME_INFORMATION: - if (!req) { - /* - * TODO: get rid of smbsrv_request argument of - * smbsrv_blob_pull_string() - */ - return NT_STATUS_NOT_IMPLEMENTED; + if (!bufinfo) { + return NT_STATUS_INTERNAL_ERROR; } BLOB_CHECK_MIN_SIZE(blob, 12); @@ -574,7 +570,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, len = IVAL(blob->data, 8); str_blob.data = blob->data+12; str_blob.length = MIN(blob->length, len); - smbsrv_blob_pull_string(req, &str_blob, 0, + smbsrv_blob_pull_string(bufinfo, &str_blob, 0, &st->rename_information.in.new_name, STR_UNICODE); if (st->rename_information.in.new_name == NULL) { diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index b57e5e1d64..00ff3862f5 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -509,7 +509,7 @@ void smbsrv_reply_negprot(struct smbsrv_request *req) return; } protos[protos_count] = NULL; - len = req_pull_ascii4(req, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE); + len = req_pull_ascii4(&req->in.bufinfo, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE); p += len; if (len == 0 || !protos[protos_count]) break; diff --git a/source4/smb_server/smb/nttrans.c b/source4/smb_server/smb/nttrans.c index dd2ec15e39..f6edc407d6 100644 --- a/source4/smb_server/smb/nttrans.c +++ b/source4/smb_server/smb/nttrans.c @@ -134,7 +134,7 @@ static NTSTATUS nttrans_create(struct smbsrv_request *req, io->ntcreatex.in.sec_desc = NULL; io->ntcreatex.in.ea_list = NULL; - req_pull_string(req, &io->ntcreatex.in.fname, + req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname, params + 53, MIN(fname_len+1, trans->in.params.length - 53), STR_NO_RANGE_CHECK | STR_TERMINATE); @@ -622,8 +622,8 @@ void smbsrv_reply_nttrans(struct smbsrv_request *req) memcpy(trans->in.setup, (char *)(req->in.vwv) + VWV(19), sizeof(uint16_t) * trans->in.setup_count); - if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, &trans->in.params) || - !req_pull_blob(req, req->in.hdr + data_ofs, data_count, &trans->in.data)) { + if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &trans->in.params) || + !req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &trans->in.data)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } diff --git a/source4/smb_server/smb/receive.c b/source4/smb_server/smb/receive.c index 3f590decca..e3d247cbc0 100644 --- a/source4/smb_server/smb/receive.c +++ b/source4/smb_server/smb/receive.c @@ -151,6 +151,9 @@ NTSTATUS smbsrv_recv_smb_request(void *private, DATA_BLOB blob) req->flags2 = SVAL(req->in.hdr, HDR_FLG2); + /* fix the bufinfo */ + smbsrv_setup_bufinfo(req); + if (!smbsrv_signing_check_incoming(req)) { smbsrv_send_error(req, NT_STATUS_ACCESS_DENIED); return NT_STATUS_OK; @@ -620,6 +623,9 @@ void smbsrv_chain_reply(struct smbsrv_request *req) req->in.data_size = data_size; req->in.ptr = data; + /* fix the bufinfo */ + smbsrv_setup_bufinfo(req); + req->chain_count++; SSVAL(req->out.vwv, VWV(0), chain_cmd); diff --git a/source4/smb_server/smb/reply.c b/source4/smb_server/smb/reply.c index aff0587bc6..40cad91062 100644 --- a/source4/smb_server/smb/reply.c +++ b/source4/smb_server/smb/reply.c @@ -58,9 +58,9 @@ void smbsrv_reply_tcon(struct smbsrv_request *req) con.tcon.level = RAW_TCON_TCON; p = req->in.data; - p += req_pull_ascii4(req, &con.tcon.in.service, p, STR_TERMINATE); - p += req_pull_ascii4(req, &con.tcon.in.password, p, STR_TERMINATE); - p += req_pull_ascii4(req, &con.tcon.in.dev, p, STR_TERMINATE); + p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.service, p, STR_TERMINATE); + p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.password, p, STR_TERMINATE); + p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.dev, p, STR_TERMINATE); if (!con.tcon.in.service || !con.tcon.in.password || !con.tcon.in.dev) { smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER); @@ -106,14 +106,14 @@ void smbsrv_reply_tcon_and_X(struct smbsrv_request *req) p = req->in.data; - if (!req_pull_blob(req, p, passlen, &con.tconx.in.password)) { + if (!req_pull_blob(&req->in.bufinfo, p, passlen, &con.tconx.in.password)) { smbsrv_send_error(req, NT_STATUS_ILL_FORMED_PASSWORD); return; } p += passlen; - p += req_pull_string(req, &con.tconx.in.path, p, -1, STR_TERMINATE); - p += req_pull_string(req, &con.tconx.in.device, p, -1, STR_ASCII); + p += req_pull_string(&req->in.bufinfo, &con.tconx.in.path, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &con.tconx.in.device, p, -1, STR_ASCII); if (!con.tconx.in.path || !con.tconx.in.device) { smbsrv_send_error(req, NT_STATUS_BAD_DEVICE_TYPE); @@ -223,7 +223,7 @@ void smbsrv_reply_chkpth(struct smbsrv_request *req) SMBSRV_TALLOC_IO_PTR(io, union smb_chkpath); SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC); - req_pull_ascii4(req, &io->chkpath.in.path, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &io->chkpath.in.path, req->in.data, STR_TERMINATE); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_chkpath(req->ntvfs, io)); } @@ -264,7 +264,7 @@ void smbsrv_reply_getatr(struct smbsrv_request *req) st->getattr.level = RAW_FILEINFO_GETATTR; /* parse request */ - req_pull_ascii4(req, &st->getattr.in.file.path, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &st->getattr.in.file.path, req->in.data, STR_TERMINATE); if (!st->getattr.in.file.path) { smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); return; @@ -290,7 +290,7 @@ void smbsrv_reply_setatr(struct smbsrv_request *req) st->setattr.in.attrib = SVAL(req->in.vwv, VWV(0)); st->setattr.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1)); - req_pull_ascii4(req, &st->setattr.in.file.path, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &st->setattr.in.file.path, req->in.data, STR_TERMINATE); if (!st->setattr.in.file.path) { smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); @@ -379,7 +379,7 @@ void smbsrv_reply_open(struct smbsrv_request *req) oi->openold.in.open_mode = SVAL(req->in.vwv, VWV(0)); oi->openold.in.search_attrs = SVAL(req->in.vwv, VWV(1)); - req_pull_ascii4(req, &oi->openold.in.fname, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &oi->openold.in.fname, req->in.data, STR_TERMINATE); if (!oi->openold.in.fname) { smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); @@ -452,7 +452,7 @@ void smbsrv_reply_open_and_X(struct smbsrv_request *req) oi->openx.in.size = IVAL(req->in.vwv, VWV(9)); oi->openx.in.timeout = IVAL(req->in.vwv, VWV(11)); - req_pull_ascii4(req, &oi->openx.in.fname, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &oi->openx.in.fname, req->in.data, STR_TERMINATE); if (!oi->openx.in.fname) { smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); @@ -502,7 +502,7 @@ void smbsrv_reply_mknew(struct smbsrv_request *req) oi->mknew.in.attrib = SVAL(req->in.vwv, VWV(0)); oi->mknew.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1)); - req_pull_ascii4(req, &oi->mknew.in.fname, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &oi->mknew.in.fname, req->in.data, STR_TERMINATE); if (!oi->mknew.in.fname) { smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); @@ -551,7 +551,7 @@ void smbsrv_reply_ctemp(struct smbsrv_request *req) /* the filename is actually a directory name, the server provides a filename in that directory */ - req_pull_ascii4(req, &oi->ctemp.in.directory, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &oi->ctemp.in.directory, req->in.data, STR_TERMINATE); if (!oi->ctemp.in.directory) { smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); @@ -576,7 +576,7 @@ void smbsrv_reply_unlink(struct smbsrv_request *req) unl->unlink.in.attrib = SVAL(req->in.vwv, VWV(0)); - req_pull_ascii4(req, &unl->unlink.in.pattern, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &unl->unlink.in.pattern, req->in.data, STR_TERMINATE); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_unlink(req->ntvfs, unl)); } @@ -958,7 +958,7 @@ void smbsrv_reply_write(struct smbsrv_request *req) io->write.in.data = req->in.data + 3; /* make sure they gave us the data they promised */ - if (req_data_oob(req, io->write.in.data, io->write.in.count)) { + if (req_data_oob(&req->in.bufinfo, io->write.in.data, io->write.in.count)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } @@ -1027,7 +1027,7 @@ void smbsrv_reply_write_and_X(struct smbsrv_request *req) } /* make sure the data is in bounds */ - if (req_data_oob(req, io->writex.in.data, io->writex.in.count)) { + if (req_data_oob(&req->in.bufinfo, io->writex.in.data, io->writex.in.count)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } @@ -1163,7 +1163,7 @@ void smbsrv_reply_writeclose(struct smbsrv_request *req) io->writeclose.in.data = req->in.data + 1; /* make sure they gave us the data they promised */ - if (req_data_oob(req, io->writeclose.in.data, io->writeclose.in.count)) { + if (req_data_oob(&req->in.bufinfo, io->writeclose.in.data, io->writeclose.in.count)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } @@ -1313,7 +1313,7 @@ void smbsrv_reply_printopen(struct smbsrv_request *req) oi->splopen.in.setup_length = SVAL(req->in.vwv, VWV(0)); oi->splopen.in.mode = SVAL(req->in.vwv, VWV(1)); - req_pull_ascii4(req, &oi->splopen.in.ident, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &oi->splopen.in.ident, req->in.data, STR_TERMINATE); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi)); } @@ -1426,7 +1426,7 @@ void smbsrv_reply_printwrite(struct smbsrv_request *req) io->splwrite.in.data = req->in.data + 3; /* make sure they gave us the data they promised */ - if (req_data_oob(req, io->splwrite.in.data, io->splwrite.in.count)) { + if (req_data_oob(&req->in.bufinfo, io->splwrite.in.data, io->splwrite.in.count)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } @@ -1449,7 +1449,7 @@ void smbsrv_reply_mkdir(struct smbsrv_request *req) SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC); io->generic.level = RAW_MKDIR_MKDIR; - req_pull_ascii4(req, &io->mkdir.in.path, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &io->mkdir.in.path, req->in.data, STR_TERMINATE); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_mkdir(req->ntvfs, io)); } @@ -1467,7 +1467,7 @@ void smbsrv_reply_rmdir(struct smbsrv_request *req) SMBSRV_TALLOC_IO_PTR(io, struct smb_rmdir); SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC); - req_pull_ascii4(req, &io->in.path, req->in.data, STR_TERMINATE); + req_pull_ascii4(&req->in.bufinfo, &io->in.path, req->in.data, STR_TERMINATE); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_rmdir(req->ntvfs, io)); } @@ -1490,8 +1490,8 @@ void smbsrv_reply_mv(struct smbsrv_request *req) io->rename.in.attrib = SVAL(req->in.vwv, VWV(0)); p = req->in.data; - p += req_pull_ascii4(req, &io->rename.in.pattern1, p, STR_TERMINATE); - p += req_pull_ascii4(req, &io->rename.in.pattern2, p, STR_TERMINATE); + p += req_pull_ascii4(&req->in.bufinfo, &io->rename.in.pattern1, p, STR_TERMINATE); + p += req_pull_ascii4(&req->in.bufinfo, &io->rename.in.pattern2, p, STR_TERMINATE); if (!io->rename.in.pattern1 || !io->rename.in.pattern2) { smbsrv_send_error(req, NT_STATUS_FOOBAR); @@ -1521,8 +1521,8 @@ void smbsrv_reply_ntrename(struct smbsrv_request *req) io->ntrename.in.cluster_size = IVAL(req->in.vwv, VWV(2)); p = req->in.data; - p += req_pull_ascii4(req, &io->ntrename.in.old_name, p, STR_TERMINATE); - p += req_pull_ascii4(req, &io->ntrename.in.new_name, p, STR_TERMINATE); + p += req_pull_ascii4(&req->in.bufinfo, &io->ntrename.in.old_name, p, STR_TERMINATE); + p += req_pull_ascii4(&req->in.bufinfo, &io->ntrename.in.new_name, p, STR_TERMINATE); if (!io->ntrename.in.old_name || !io->ntrename.in.new_name) { smbsrv_send_error(req, NT_STATUS_FOOBAR); @@ -1568,8 +1568,8 @@ void smbsrv_reply_copy(struct smbsrv_request *req) cp->in.flags = SVAL(req->in.vwv, VWV(2)); p = req->in.data; - p += req_pull_ascii4(req, &cp->in.path1, p, STR_TERMINATE); - p += req_pull_ascii4(req, &cp->in.path2, p, STR_TERMINATE); + p += req_pull_ascii4(&req->in.bufinfo, &cp->in.path1, p, STR_TERMINATE); + p += req_pull_ascii4(&req->in.bufinfo, &cp->in.path2, p, STR_TERMINATE); if (!cp->in.path1 || !cp->in.path2) { smbsrv_send_error(req, NT_STATUS_FOOBAR); @@ -1638,7 +1638,7 @@ void smbsrv_reply_lockingX(struct smbsrv_request *req) } /* make sure we got the promised data */ - if (req_data_oob(req, req->in.data, total_locks * lck_size)) { + if (req_data_oob(&req->in.bufinfo, req->in.data, total_locks * lck_size)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } @@ -1877,22 +1877,22 @@ static void reply_sesssetup_old(struct smbsrv_request *req) passlen = SVAL(req->in.vwv, VWV(7)); /* check the request isn't malformed */ - if (req_data_oob(req, req->in.data, passlen)) { + if (req_data_oob(&req->in.bufinfo, req->in.data, passlen)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } p = req->in.data; - if (!req_pull_blob(req, p, passlen, &io->old.in.password)) { + if (!req_pull_blob(&req->in.bufinfo, p, passlen, &io->old.in.password)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } p += passlen; - p += req_pull_string(req, &io->old.in.user, p, -1, STR_TERMINATE); - p += req_pull_string(req, &io->old.in.domain, p, -1, STR_TERMINATE); - p += req_pull_string(req, &io->old.in.os, p, -1, STR_TERMINATE); - p += req_pull_string(req, &io->old.in.lanman, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->old.in.user, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->old.in.domain, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->old.in.os, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->old.in.lanman, p, -1, STR_TERMINATE); /* call the generic handler */ smbsrv_sesssetup_backend(req, io); @@ -1921,28 +1921,28 @@ static void reply_sesssetup_nt1(struct smbsrv_request *req) io->nt1.in.capabilities = IVAL(req->in.vwv, VWV(11)); /* check the request isn't malformed */ - if (req_data_oob(req, req->in.data, passlen1) || - req_data_oob(req, req->in.data + passlen1, passlen2)) { + if (req_data_oob(&req->in.bufinfo, req->in.data, passlen1) || + req_data_oob(&req->in.bufinfo, req->in.data + passlen1, passlen2)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } p = req->in.data; - if (!req_pull_blob(req, p, passlen1, &io->nt1.in.password1)) { + if (!req_pull_blob(&req->in.bufinfo, p, passlen1, &io->nt1.in.password1)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } p += passlen1; - if (!req_pull_blob(req, p, passlen2, &io->nt1.in.password2)) { + if (!req_pull_blob(&req->in.bufinfo, p, passlen2, &io->nt1.in.password2)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } p += passlen2; - p += req_pull_string(req, &io->nt1.in.user, p, -1, STR_TERMINATE); - p += req_pull_string(req, &io->nt1.in.domain, p, -1, STR_TERMINATE); - p += req_pull_string(req, &io->nt1.in.os, p, -1, STR_TERMINATE); - p += req_pull_string(req, &io->nt1.in.lanman, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->nt1.in.user, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->nt1.in.domain, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->nt1.in.os, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->nt1.in.lanman, p, -1, STR_TERMINATE); /* call the generic handler */ smbsrv_sesssetup_backend(req, io); @@ -1971,15 +1971,15 @@ static void reply_sesssetup_spnego(struct smbsrv_request *req) io->spnego.in.capabilities = IVAL(req->in.vwv, VWV(10)); p = req->in.data; - if (!req_pull_blob(req, p, blob_len, &io->spnego.in.secblob)) { + if (!req_pull_blob(&req->in.bufinfo, p, blob_len, &io->spnego.in.secblob)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } p += blob_len; - p += req_pull_string(req, &io->spnego.in.os, p, -1, STR_TERMINATE); - p += req_pull_string(req, &io->spnego.in.lanman, p, -1, STR_TERMINATE); - p += req_pull_string(req, &io->spnego.in.workgroup, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->spnego.in.os, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->spnego.in.lanman, p, -1, STR_TERMINATE); + p += req_pull_string(&req->in.bufinfo, &io->spnego.in.workgroup, p, -1, STR_TERMINATE); /* call the generic handler */ smbsrv_sesssetup_backend(req, io); @@ -2199,7 +2199,7 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req) fname_len++; } - req_pull_string(req, &io->ntcreatex.in.fname, req->in.data, fname_len, STR_TERMINATE); + req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname, req->in.data, fname_len, STR_TERMINATE); if (!io->ntcreatex.in.fname) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; diff --git a/source4/smb_server/smb/request.c b/source4/smb_server/smb/request.c index 8f6d664500..724055499b 100644 --- a/source4/smb_server/smb/request.c +++ b/source4/smb_server/smb/request.c @@ -33,6 +33,17 @@ /* we over allocate the data buffer to prevent too many realloc calls */ #define REQ_OVER_ALLOCATION 0 +/* setup the bufinfo used for strings and range checking */ +void smbsrv_setup_bufinfo(struct smbsrv_request *req) +{ + req->in.bufinfo.mem_ctx = req; + req->in.bufinfo.unicode = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false; + req->in.bufinfo.align_base = req->in.buffer; + req->in.bufinfo.data = req->in.data; + req->in.bufinfo.data_size = req->in.data_size; +} + + static int smbsrv_request_destructor(struct smbsrv_request *req) { DLIST_REMOVE(req->smb_conn->requests, req); @@ -461,13 +472,13 @@ size_t req_append_var_block(struct smbsrv_request *req, on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the packet is returned */ -static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags) +static size_t req_pull_ucs2(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2, alignment=0; ssize_t ret; char *dest2; - if (!(flags & STR_NOALIGN) && ucs2_align(req->in.buffer, src, flags)) { + if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) { src++; alignment=1; if (byte_len != -1) { @@ -478,7 +489,7 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const if (flags & STR_NO_RANGE_CHECK) { src_len = byte_len; } else { - src_len = req->in.data_size - PTR_DIFF(src, req->in.data); + src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data); if (byte_len != -1 && src_len > byte_len) { src_len = byte_len; } @@ -491,11 +502,11 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const src_len2 = utf16_len_n(src, src_len); if (src_len2 == 0) { - *dest = talloc_strdup(req, ""); + *dest = talloc_strdup(bufinfo->mem_ctx, ""); return src_len2 + alignment; } - ret = convert_string_talloc(req, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2); + ret = convert_string_talloc(bufinfo->mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2); if (ret == -1) { *dest = NULL; @@ -519,7 +530,7 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the packet is returned */ -static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags) +static size_t req_pull_ascii(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags) { int src_len, src_len2; ssize_t ret; @@ -528,7 +539,7 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons if (flags & STR_NO_RANGE_CHECK) { src_len = byte_len; } else { - src_len = req->in.data_size - PTR_DIFF(src, req->in.data); + src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data); if (src_len < 0) { *dest = NULL; return 0; @@ -544,7 +555,7 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons src_len2++; } - ret = convert_string_talloc(req, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2); + ret = convert_string_talloc(bufinfo->mem_ctx, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2); if (ret == -1) { *dest = NULL; @@ -568,14 +579,14 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons on failure zero is returned and *dest is set to NULL, otherwise the number of bytes consumed in the packet is returned */ -size_t req_pull_string(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags) +size_t req_pull_string(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags) { if (!(flags & STR_ASCII) && - (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) { - return req_pull_ucs2(req, dest, src, byte_len, flags); + (((flags & STR_UNICODE) || bufinfo->unicode))) { + return req_pull_ucs2(bufinfo, dest, src, byte_len, flags); } - return req_pull_ascii(req, dest, src, byte_len, flags); + return req_pull_ascii(bufinfo, dest, src, byte_len, flags); } @@ -588,13 +599,13 @@ size_t req_pull_string(struct smbsrv_request *req, const char **dest, const uint on failure *dest is set to the zero length string. This seems to match win2000 behaviour */ -size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint8_t *src, uint_t flags) +size_t req_pull_ascii4(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, uint_t flags) { ssize_t ret; - if (PTR_DIFF(src, req->in.data) + 1 > req->in.data_size) { + if (PTR_DIFF(src, bufinfo->data) + 1 > bufinfo->data_size) { /* win2000 treats this as the empty string! */ - (*dest) = talloc_strdup(req, ""); + (*dest) = talloc_strdup(bufinfo->mem_ctx, ""); return 0; } @@ -603,9 +614,9 @@ size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint behaviour */ src++; - ret = req_pull_string(req, dest, src, -1, flags); + ret = req_pull_string(bufinfo, dest, src, -1, flags); if (ret == -1) { - (*dest) = talloc_strdup(req, ""); + (*dest) = talloc_strdup(bufinfo->mem_ctx, ""); return 1; } @@ -617,30 +628,30 @@ size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint return false if any part is outside the data portion of the packet */ -bool req_pull_blob(struct smbsrv_request *req, const uint8_t *src, int len, DATA_BLOB *blob) +bool req_pull_blob(struct request_bufinfo *bufinfo, const uint8_t *src, int len, DATA_BLOB *blob) { - if (len != 0 && req_data_oob(req, src, len)) { + if (len != 0 && req_data_oob(bufinfo, src, len)) { return false; } - (*blob) = data_blob_talloc(req, src, len); + (*blob) = data_blob_talloc(bufinfo->mem_ctx, src, len); return true; } /* check that a lump of data in a request is within the bounds of the data section of the packet */ -bool req_data_oob(struct smbsrv_request *req, const uint8_t *ptr, uint32_t count) +bool req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count) { if (count == 0) { return false; } /* be careful with wraparound! */ - if (ptr < req->in.data || - ptr >= req->in.data + req->in.data_size || - count > req->in.data_size || - ptr + count > req->in.data + req->in.data_size) { + if (ptr < bufinfo->data || + ptr >= bufinfo->data + bufinfo->data_size || + count > bufinfo->data_size || + ptr + count > bufinfo->data + bufinfo->data_size) { return true; } return false; diff --git a/source4/smb_server/smb/search.c b/source4/smb_server/smb/search.c index ccf2ff7365..90b2331271 100644 --- a/source4/smb_server/smb/search.c +++ b/source4/smb_server/smb/search.c @@ -129,14 +129,14 @@ void smbsrv_reply_search(struct smbsrv_request *req) SMBSRV_TALLOC_IO_PTR(sf, union smb_search_first); p = req->in.data; - p += req_pull_ascii4(req, &sf->search_first.in.pattern, + p += req_pull_ascii4(&req->in.bufinfo, &sf->search_first.in.pattern, p, STR_TERMINATE); if (!sf->search_first.in.pattern) { smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND); return; } - if (req_data_oob(req, p, 3)) { + if (req_data_oob(&req->in.bufinfo, p, 3)) { smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -167,7 +167,7 @@ void smbsrv_reply_search(struct smbsrv_request *req) union smb_search_next *sn; if (resume_key_length != 21 || - req_data_oob(req, p, 21) || + req_data_oob(&req->in.bufinfo, p, 21) || level == RAW_SEARCH_FUNIQUE) { smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER); return; @@ -242,13 +242,13 @@ void smbsrv_reply_fclose(struct smbsrv_request *req) SMBSRV_SETUP_NTVFS_REQUEST(reply_fclose_send, NTVFS_ASYNC_STATE_MAY_ASYNC); p = req->in.data; - p += req_pull_ascii4(req, &pattern, p, STR_TERMINATE); + p += req_pull_ascii4(&req->in.bufinfo, &pattern, p, STR_TERMINATE); if (pattern && *pattern) { smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER); return; } - if (req_data_oob(req, p, 3)) { + if (req_data_oob(&req->in.bufinfo, p, 3)) { smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -264,7 +264,7 @@ void smbsrv_reply_fclose(struct smbsrv_request *req) return; } - if (req_data_oob(req, p, 21)) { + if (req_data_oob(&req->in.bufinfo, p, 21)) { smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER); return; } diff --git a/source4/smb_server/smb/trans2.c b/source4/smb_server/smb/trans2.c index 45ea234d09..3336169bb0 100644 --- a/source4/smb_server/smb/trans2.c +++ b/source4/smb_server/smb/trans2.c @@ -248,7 +248,7 @@ static NTSTATUS trans2_open(struct smbsrv_request *req, struct trans_op *op) io->t2open.in.num_eas = 0; io->t2open.in.eas = NULL; - smbsrv_blob_pull_string(req, &trans->in.params, 28, &io->t2open.in.fname, 0); + smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 28, &io->t2open.in.fname, 0); if (io->t2open.in.fname == NULL) { return NT_STATUS_FOOBAR; } @@ -296,7 +296,7 @@ static NTSTATUS trans2_mkdir(struct smbsrv_request *req, struct trans_op *op) NT_STATUS_HAVE_NO_MEMORY(io); io->t2mkdir.level = RAW_MKDIR_T2MKDIR; - smbsrv_blob_pull_string(req, &trans->in.params, 4, &io->t2mkdir.in.path, 0); + smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 4, &io->t2mkdir.in.path, 0); if (io->t2mkdir.in.path == NULL) { return NT_STATUS_FOOBAR; } @@ -461,7 +461,7 @@ static NTSTATUS trans2_qpathinfo(struct smbsrv_request *req, struct trans_op *op level = SVAL(trans->in.params.data, 0); - smbsrv_blob_pull_string(req, &trans->in.params, 6, &st->generic.in.file.path, 0); + smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 6, &st->generic.in.file.path, 0); if (st->generic.in.file.path == NULL) { return NT_STATUS_FOOBAR; } @@ -602,7 +602,7 @@ static NTSTATUS trans2_parse_sfileinfo(struct smbsrv_request *req, return smbsrv_pull_passthru_sfileinfo(st, passthru_level, st, blob, SMBSRV_REQ_DEFAULT_STR_FLAGS(req), - req); + &req->in.bufinfo); } /* @@ -661,7 +661,7 @@ static NTSTATUS trans2_setpathinfo(struct smbsrv_request *req, struct trans_op * level = SVAL(trans->in.params.data, 0); - smbsrv_blob_pull_string(req, &trans->in.params, 6, &st->generic.in.file.path, 0); + smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 6, &st->generic.in.file.path, 0); if (st->generic.in.file.path == NULL) { return NT_STATUS_FOOBAR; } @@ -859,7 +859,7 @@ static NTSTATUS trans2_findfirst(struct smbsrv_request *req, struct trans_op *op level = SVAL(trans->in.params.data, 6); search->t2ffirst.in.storage_type = IVAL(trans->in.params.data, 8); - smbsrv_blob_pull_string(req, &trans->in.params, 12, &search->t2ffirst.in.pattern, 0); + smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 12, &search->t2ffirst.in.pattern, 0); if (search->t2ffirst.in.pattern == NULL) { return NT_STATUS_FOOBAR; } @@ -945,7 +945,7 @@ static NTSTATUS trans2_findnext(struct smbsrv_request *req, struct trans_op *op) search->t2fnext.in.resume_key = IVAL(trans->in.params.data, 6); search->t2fnext.in.flags = SVAL(trans->in.params.data, 10); - smbsrv_blob_pull_string(req, &trans->in.params, 12, &search->t2fnext.in.last_name, 0); + smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 12, &search->t2fnext.in.last_name, 0); if (search->t2fnext.in.last_name == NULL) { return NT_STATUS_FOOBAR; } @@ -1240,11 +1240,11 @@ static void reply_trans_generic(struct smbsrv_request *req, uint8_t command) } if (command == SMBtrans) { - req_pull_string(req, &trans->in.trans_name, req->in.data, -1, STR_TERMINATE); + req_pull_string(&req->in.bufinfo, &trans->in.trans_name, req->in.data, -1, STR_TERMINATE); } - if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, &trans->in.params) || - !req_pull_blob(req, req->in.hdr + data_ofs, data_count, &trans->in.data)) { + if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &trans->in.params) || + !req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &trans->in.data)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } @@ -1302,8 +1302,8 @@ static void reply_transs_generic(struct smbsrv_request *req, uint8_t command) data_ofs = SVAL(req->in.vwv, VWV(6)); data_disp = SVAL(req->in.vwv, VWV(7)); - if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, ¶ms) || - !req_pull_blob(req, req->in.hdr + data_ofs, data_count, &data)) { + if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, ¶ms) || + !req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &data)) { smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER); return; } diff --git a/source4/smb_server/smb2/fileinfo.c b/source4/smb_server/smb2/fileinfo.c index 00c455e351..e375b7308f 100644 --- a/source4/smb_server/smb2/fileinfo.c +++ b/source4/smb_server/smb2/fileinfo.c @@ -268,7 +268,7 @@ static NTSTATUS smb2srv_setinfo_file(struct smb2srv_setinfo_op *op, uint8_t smb2 status = smbsrv_pull_passthru_sfileinfo(io, io->generic.level, io, &op->info->in.blob, - STR_UNICODE, NULL); + STR_UNICODE, &op->req->in.bufinfo); NT_STATUS_NOT_OK_RETURN(status); return ntvfs_setfileinfo(op->req->ntvfs, io); diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 7c295c05ab..578eadbe8f 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -238,6 +238,8 @@ void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req) req->in.body_size = body_fixed_size; req->in.dynamic = NULL; + smb2srv_setup_bufinfo(req); + SIVAL(req->in.hdr, 0, SMB2_MAGIC); SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0); diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c index 393b3f0cc5..58070065fc 100644 --- a/source4/smb_server/smb2/receive.c +++ b/source4/smb_server/smb2/receive.c @@ -30,6 +30,22 @@ #include "ntvfs/ntvfs.h" #include "param/param.h" + +/* fill in the bufinfo */ +void smb2srv_setup_bufinfo(struct smb2srv_request *req) +{ + req->in.bufinfo.mem_ctx = req; + req->in.bufinfo.unicode = true; + req->in.bufinfo.align_base = req->in.buffer; + if (req->in.dynamic) { + req->in.bufinfo.data = req->in.dynamic; + req->in.bufinfo.data_size = req->in.body_size - req->in.body_fixed; + } else { + req->in.bufinfo.data = NULL; + req->in.bufinfo.data_size = 0; + } +} + static int smb2srv_request_destructor(struct smb2srv_request *req) { DLIST_REMOVE(req->smb_conn->requests2.list, req); @@ -180,6 +196,8 @@ static void smb2srv_chain_reply(struct smb2srv_request *p_req) } } + smb2srv_setup_bufinfo(req); + if (p_req->chained_file_handle) { memcpy(req->_chained_file_handle, p_req->_chained_file_handle, @@ -430,6 +448,8 @@ NTSTATUS smbsrv_recv_smb2_request(void *private, DATA_BLOB blob) } } + smb2srv_setup_bufinfo(req); + /* * TODO: - make sure the length field is 64 * - make sure it's a request diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c index b375ce6b4b..50094b806d 100644 --- a/source4/smb_server/smb2/tcon.c +++ b/source4/smb_server/smb2/tcon.c @@ -55,6 +55,8 @@ static NTSTATUS smb2srv_send_oplock_break(void *p, struct ntvfs_handle *h, uint8 req->seqnum = UINT64_MAX; + smb2srv_setup_bufinfo(req); + SIVAL(req->in.hdr, 0, SMB2_MAGIC); SSVAL(req->in.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); SSVAL(req->in.hdr, SMB2_HDR_EPOCH, 0); diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h index bb0673b7d0..776fe1b71b 100644 --- a/source4/smb_server/smb_server.h +++ b/source4/smb_server/smb_server.h @@ -254,8 +254,8 @@ struct smbsrv_request { /* the sequence number for signing */ uint64_t seq_num; - struct request_buffer in; - struct request_buffer out; + struct smb_request_buffer in; + struct smb_request_buffer out; }; enum security_types {SEC_SHARE,SEC_USER}; -- cgit From 839ab724dc2d204bfbb0693aeed64f6f83a4266b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 12:30:31 +1100 Subject: Fixed SMB2 rename operations from Vista clients We needed a flag in bufinfo to mark packets as SMB2, as it seems that SMB2 uses a different format for the RenameInformation buffer than SMB does Also handle the fact that SMB2 clients give the full path to the target file in the rename, not a relative path (This used to be commit 52d7972d95ddc19d22a4187b4d4428a6c3ed32d5) --- source4/smb_server/blob.c | 27 ++++++++++++++++++--------- source4/smb_server/smb/request.c | 7 +++++-- source4/smb_server/smb2/receive.c | 2 +- 3 files changed, 24 insertions(+), 12 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/blob.c b/source4/smb_server/blob.c index caf6fb447d..795e7ce585 100644 --- a/source4/smb_server/blob.c +++ b/source4/smb_server/blob.c @@ -523,7 +523,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, int default_str_flags, struct request_bufinfo *bufinfo) { - uint32_t len; + uint32_t len, ofs; DATA_BLOB str_blob; switch (level) { @@ -563,14 +563,23 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, if (!bufinfo) { return NT_STATUS_INTERNAL_ERROR; } - BLOB_CHECK_MIN_SIZE(blob, 12); - - st->rename_information.in.overwrite = CVAL(blob->data, 0); - st->rename_information.in.root_fid = IVAL(blob->data, 4); - len = IVAL(blob->data, 8); - str_blob.data = blob->data+12; - str_blob.length = MIN(blob->length, len); - smbsrv_blob_pull_string(bufinfo, &str_blob, 0, + if (bufinfo->flags & BUFINFO_FLAG_SMB2) { + /* SMB2 uses a different format for rename information */ + BLOB_CHECK_MIN_SIZE(blob, 20); + st->rename_information.in.overwrite = CVAL(blob->data, 0); + st->rename_information.in.root_fid = BVAL(blob->data, 4); + len = IVAL(blob->data,16); + ofs = 20; + } else { + BLOB_CHECK_MIN_SIZE(blob, 12); + st->rename_information.in.overwrite = CVAL(blob->data, 0); + st->rename_information.in.root_fid = IVAL(blob->data, 4); + len = IVAL(blob->data, 8); + ofs = 12; + } + str_blob = *blob; + str_blob.length = MIN(str_blob.length, ofs+len); + smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, &st->rename_information.in.new_name, STR_UNICODE); if (st->rename_information.in.new_name == NULL) { diff --git a/source4/smb_server/smb/request.c b/source4/smb_server/smb/request.c index 724055499b..d7f3793f23 100644 --- a/source4/smb_server/smb/request.c +++ b/source4/smb_server/smb/request.c @@ -37,7 +37,10 @@ void smbsrv_setup_bufinfo(struct smbsrv_request *req) { req->in.bufinfo.mem_ctx = req; - req->in.bufinfo.unicode = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false; + req->in.bufinfo.flags = 0; + if (req->flags2 & FLAGS2_UNICODE_STRINGS) { + req->in.bufinfo.flags |= BUFINFO_FLAG_UNICODE; + } req->in.bufinfo.align_base = req->in.buffer; req->in.bufinfo.data = req->in.data; req->in.bufinfo.data_size = req->in.data_size; @@ -582,7 +585,7 @@ static size_t req_pull_ascii(struct request_bufinfo *bufinfo, const char **dest, size_t req_pull_string(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags) { if (!(flags & STR_ASCII) && - (((flags & STR_UNICODE) || bufinfo->unicode))) { + (((flags & STR_UNICODE) || (bufinfo->flags & BUFINFO_FLAG_UNICODE)))) { return req_pull_ucs2(bufinfo, dest, src, byte_len, flags); } diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c index 58070065fc..dea7c9e79e 100644 --- a/source4/smb_server/smb2/receive.c +++ b/source4/smb_server/smb2/receive.c @@ -35,7 +35,7 @@ void smb2srv_setup_bufinfo(struct smb2srv_request *req) { req->in.bufinfo.mem_ctx = req; - req->in.bufinfo.unicode = true; + req->in.bufinfo.flags = BUFINFO_FLAG_UNICODE | BUFINFO_FLAG_SMB2; req->in.bufinfo.align_base = req->in.buffer; if (req->in.dynamic) { req->in.bufinfo.data = req->in.dynamic; -- cgit From 4a04a5e620a4666fc123d04cb96ef391de72c469 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 14:54:21 +1100 Subject: A better way to handle the different format of RenameInformation in SMB2 We now define a separate info level RAW_SFILEINFO_RENAME_INFORMATION_SMB2 and set that level when handling SMB2 packets. This makes the parsers clearer. (This used to be commit f6cdf3f1177f63d80be757f007eb15380839b4f5) --- source4/smb_server/blob.c | 38 +++++++++++++++++++++++++------------- source4/smb_server/smb2/fileinfo.c | 5 +++++ 2 files changed, 30 insertions(+), 13 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/blob.c b/source4/smb_server/blob.c index 795e7ce585..8c813204f3 100644 --- a/source4/smb_server/blob.c +++ b/source4/smb_server/blob.c @@ -563,20 +563,32 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, if (!bufinfo) { return NT_STATUS_INTERNAL_ERROR; } - if (bufinfo->flags & BUFINFO_FLAG_SMB2) { - /* SMB2 uses a different format for rename information */ - BLOB_CHECK_MIN_SIZE(blob, 20); - st->rename_information.in.overwrite = CVAL(blob->data, 0); - st->rename_information.in.root_fid = BVAL(blob->data, 4); - len = IVAL(blob->data,16); - ofs = 20; - } else { - BLOB_CHECK_MIN_SIZE(blob, 12); - st->rename_information.in.overwrite = CVAL(blob->data, 0); - st->rename_information.in.root_fid = IVAL(blob->data, 4); - len = IVAL(blob->data, 8); - ofs = 12; + BLOB_CHECK_MIN_SIZE(blob, 12); + st->rename_information.in.overwrite = CVAL(blob->data, 0); + st->rename_information.in.root_fid = IVAL(blob->data, 4); + len = IVAL(blob->data, 8); + ofs = 12; + str_blob = *blob; + str_blob.length = MIN(str_blob.length, ofs+len); + smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, + &st->rename_information.in.new_name, + STR_UNICODE); + if (st->rename_information.in.new_name == NULL) { + return NT_STATUS_FOOBAR; + } + + return NT_STATUS_OK; + + case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: + /* SMB2 uses a different format for rename information */ + if (!bufinfo) { + return NT_STATUS_INTERNAL_ERROR; } + BLOB_CHECK_MIN_SIZE(blob, 20); + st->rename_information.in.overwrite = CVAL(blob->data, 0); + st->rename_information.in.root_fid = BVAL(blob->data, 8); + len = IVAL(blob->data,16); + ofs = 20; str_blob = *blob; str_blob.length = MIN(str_blob.length, ofs+len); smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, diff --git a/source4/smb_server/smb2/fileinfo.c b/source4/smb_server/smb2/fileinfo.c index e375b7308f..e6521991ef 100644 --- a/source4/smb_server/smb2/fileinfo.c +++ b/source4/smb_server/smb2/fileinfo.c @@ -266,6 +266,11 @@ static NTSTATUS smb2srv_setinfo_file(struct smb2srv_setinfo_op *op, uint8_t smb2 io->generic.level = smb2_level + 1000; io->generic.in.file.ntvfs = op->info->in.file.ntvfs; + /* handle cases that don't map directly */ + if (io->generic.level == RAW_SFILEINFO_RENAME_INFORMATION) { + io->generic.level = RAW_SFILEINFO_RENAME_INFORMATION_SMB2; + } + status = smbsrv_pull_passthru_sfileinfo(io, io->generic.level, io, &op->info->in.blob, STR_UNICODE, &op->req->in.bufinfo); -- cgit From b640f475be9b0f83e7812a5c7756344c5891cba3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 17:11:36 +1100 Subject: updated SMB2 code for getinfo according to WSPP docs - Updated getinfo structures and field names - also updated the protocol revision number handling to reflect new docs (This used to be commit 3aaa2e86d94675c6c68d66d75292c3e34bfbc81b) --- source4/smb_server/smb2/fileinfo.c | 42 ++++++++++++++++++-------------------- source4/smb_server/smb2/negprot.c | 9 ++++---- 2 files changed, 25 insertions(+), 26 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/fileinfo.c b/source4/smb_server/smb2/fileinfo.c index e6521991ef..d6db61eaba 100644 --- a/source4/smb_server/smb2/fileinfo.c +++ b/source4/smb_server/smb2/fileinfo.c @@ -79,19 +79,21 @@ static NTSTATUS smb2srv_getinfo_file_send(struct smb2srv_getinfo_op *op) static NTSTATUS smb2srv_getinfo_file(struct smb2srv_getinfo_op *op, uint8_t smb2_level) { union smb_fileinfo *io; + uint16_t level; io = talloc(op, union smb_fileinfo); NT_STATUS_HAVE_NO_MEMORY(io); - switch (op->info->in.level) { + level = op->info->in.info_type | (op->info->in.info_class << 8); + switch (level) { case RAW_FILEINFO_SMB2_ALL_EAS: - io->all_eas.level = op->info->in.level; + io->all_eas.level = level; io->all_eas.in.file.ntvfs = op->info->in.file.ntvfs; - io->all_eas.in.continue_flags = op->info->in.flags2; + io->all_eas.in.continue_flags = op->info->in.getinfo_flags; break; case RAW_FILEINFO_SMB2_ALL_INFORMATION: - io->all_info2.level = op->info->in.level; + io->all_info2.level = level; io->all_info2.in.file.ntvfs = op->info->in.file.ntvfs; break; @@ -166,7 +168,7 @@ static NTSTATUS smb2srv_getinfo_security(struct smb2srv_getinfo_op *op, uint8_t io->query_secdesc.level = RAW_FILEINFO_SEC_DESC; io->query_secdesc.in.file.ntvfs = op->info->in.file.ntvfs; - io->query_secdesc.in.secinfo_flags = op->info->in.flags; + io->query_secdesc.in.secinfo_flags = op->info->in.additional_information; op->io_ptr = io; op->send_fn = smb2srv_getinfo_security_send; @@ -179,23 +181,17 @@ static NTSTATUS smb2srv_getinfo_security(struct smb2srv_getinfo_op *op, uint8_t static NTSTATUS smb2srv_getinfo_backend(struct smb2srv_getinfo_op *op) { - uint8_t smb2_class; - uint8_t smb2_level; - - smb2_class = 0xFF & op->info->in.level; - smb2_level = 0xFF & (op->info->in.level>>8); - - switch (smb2_class) { + switch (op->info->in.info_type) { case SMB2_GETINFO_FILE: - return smb2srv_getinfo_file(op, smb2_level); + return smb2srv_getinfo_file(op, op->info->in.info_class); case SMB2_GETINFO_FS: - return smb2srv_getinfo_fs(op, smb2_level); + return smb2srv_getinfo_fs(op, op->info->in.info_class); case SMB2_GETINFO_SECURITY: - return smb2srv_getinfo_security(op, smb2_level); + return smb2srv_getinfo_security(op, op->info->in.info_class); - case 0x04: + case SMB2_GETINFO_QUOTA: return NT_STATUS_NOT_SUPPORTED; } @@ -217,13 +213,15 @@ void smb2srv_getinfo_recv(struct smb2srv_request *req) op->send_fn = NULL; SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_getinfo_send, NTVFS_ASYNC_STATE_MAY_ASYNC); - info->in.level = SVAL(req->in.body, 0x02); - info->in.max_response_size = IVAL(req->in.body, 0x04); - info->in.unknown1 = IVAL(req->in.body, 0x08); - info->in.unknown2 = IVAL(req->in.body, 0x0C); - info->in.flags = IVAL(req->in.body, 0x10); - info->in.flags2 = IVAL(req->in.body, 0x14); + info->in.info_type = CVAL(req->in.body, 0x02); + info->in.info_class = CVAL(req->in.body, 0x03); + info->in.output_buffer_length = IVAL(req->in.body, 0x04); + info->in.reserved = IVAL(req->in.body, 0x0C); + info->in.additional_information = IVAL(req->in.body, 0x10); + info->in.getinfo_flags = IVAL(req->in.body, 0x14); info->in.file.ntvfs = smb2srv_pull_handle(req, req->in.body, 0x18); + SMB2SRV_CHECK(smb2_pull_o16As32_blob(&req->in, op, + req->in.body+0x08, &info->in.blob)); SMB2SRV_CHECK_FILE_HANDLE(info->in.file.ntvfs); SMB2SRV_CALL_NTVFS_BACKEND(smb2srv_getinfo_backend(op)); diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 578eadbe8f..5bbd7f7d5e 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -93,12 +93,14 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 struct timeval current_time; struct timeval boot_time; - /* we only do dialect 0 for now */ + /* we only do one dialect for now */ if (io->in.dialect_count < 1) { return NT_STATUS_NOT_SUPPORTED; } - if (io->in.dialects[0] != 0) { + if (io->in.dialects[0] != 0 && + io->in.dialects[0] != SMB2_DIALECT_REVISION) { DEBUG(0,("Got unexpected SMB2 dialect %u\n", io->in.dialects[0])); + return NT_STATUS_NOT_SUPPORTED; } req->smb_conn->negotiate.protocol = PROTOCOL_SMB2; @@ -108,8 +110,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 ZERO_STRUCT(io->out); io->out.security_mode = 0; /* no signing yet */ - /* choose the first dialect offered for now */ - io->out.dialect_revision = io->in.dialects[0]; + io->out.dialect_revision = SMB2_DIALECT_REVISION; io->out.capabilities = 0; io->out.max_transact_size = 0x10000; io->out.max_read_size = 0x10000; -- cgit From e33177001cdd7d55e45bb9c6ed3f39bf33a9da84 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 14 Feb 2008 12:03:34 +0100 Subject: Remove type before variables in data.mk (This used to be commit 3c1a7c0dcc56ed5595e31a8df023a04ae95bfca5) --- source4/smb_server/smb/config.mk | 2 +- source4/smb_server/smb2/config.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb/config.mk b/source4/smb_server/smb/config.mk index 22151ebd3b..ddadc29ddb 100644 --- a/source4/smb_server/smb/config.mk +++ b/source4/smb_server/smb/config.mk @@ -16,6 +16,6 @@ OBJ_FILES = \ signing.o PUBLIC_DEPENDENCIES = \ ntvfs LIBPACKET CREDENTIALS -LDFLAGS = $(SUBSYSTEM_SMB_SERVER_OUTPUT) +LDFLAGS = $(SMB_SERVER_OUTPUT) # End SUBSYSTEM SMB_PROTOCOL ####################### diff --git a/source4/smb_server/smb2/config.mk b/source4/smb_server/smb2/config.mk index b878d404c8..b7d7cdc282 100644 --- a/source4/smb_server/smb2/config.mk +++ b/source4/smb_server/smb2/config.mk @@ -13,6 +13,6 @@ OBJ_FILES = \ keepalive.o PUBLIC_DEPENDENCIES = \ ntvfs LIBPACKET LIBCLI_SMB2 -LDFLAGS = $(SUBSYSTEM_SMB_SERVER_OUTPUT) +LDFLAGS = $(SMB_SERVER_OUTPUT) # End SUBSYSTEM SMB2_PROTOCOL ####################### -- cgit From 5fb241e5d33024dd7af1e7ec5cbdefbf144be6a1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Feb 2008 14:54:14 +1100 Subject: 3 places where the VFS backend doesn't handle NULL strings. (This used to be commit cf109460aff5a8437ab7eba05e4d7316a131080e) --- source4/smb_server/smb2/fileio.c | 5 +++++ source4/smb_server/smb2/find.c | 5 +++++ source4/smb_server/smb2/tcon.c | 5 +++++ 3 files changed, 15 insertions(+) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/fileio.c b/source4/smb_server/smb2/fileio.c index 567243ba94..0e3df56b42 100644 --- a/source4/smb_server/smb2/fileio.c +++ b/source4/smb_server/smb2/fileio.c @@ -80,6 +80,11 @@ void smb2srv_create_recv(struct smb2srv_request *req) /* TODO: parse the blob */ ZERO_STRUCT(io->smb2.in.eas); + /* the VFS backend does not yet handle NULL filenames */ + if (io->smb2.in.fname == NULL) { + io->smb2.in.fname = ""; + } + SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, io)); } diff --git a/source4/smb_server/smb2/find.c b/source4/smb_server/smb2/find.c index c594adf7a0..6018f1958f 100644 --- a/source4/smb_server/smb2/find.c +++ b/source4/smb_server/smb2/find.c @@ -161,6 +161,11 @@ void smb2srv_find_recv(struct smb2srv_request *req) SMB2SRV_CHECK(smb2_pull_o16s16_string(&req->in, info, req->in.body+0x18, &info->in.pattern)); info->in.max_response_size = IVAL(req->in.body, 0x1C); + /* the VFS backend does not yet handle NULL patterns */ + if (info->in.pattern == NULL) { + info->in.pattern = ""; + } + SMB2SRV_CHECK_FILE_HANDLE(info->in.file.ntvfs); SMB2SRV_CALL_NTVFS_BACKEND(smb2srv_find_backend(state)); } diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c index 50094b806d..7f7d558b16 100644 --- a/source4/smb_server/smb2/tcon.c +++ b/source4/smb_server/smb2/tcon.c @@ -394,6 +394,11 @@ void smb2srv_tcon_recv(struct smb2srv_request *req) io->smb2.in.reserved = SVAL(req->in.body, 0x02); SMB2SRV_CHECK(smb2_pull_o16s16_string(&req->in, io, req->in.body+0x04, &io->smb2.in.path)); + /* the VFS backend does not yet handle NULL paths */ + if (io->smb2.in.path == NULL) { + io->smb2.in.path = ""; + } + req->status = smb2srv_tcon_backend(req, io); if (req->control_flags & SMB2SRV_REQ_CTRL_FLAG_NOT_REPLY) { -- cgit From 80cbff3d011ad9264462812f57991ed0393b385e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Feb 2008 16:02:33 +0100 Subject: Fix build with partial linking. (This used to be commit bfad9610c472e8d7e3656e19c8dbb6b85727dc13) --- source4/smb_server/smb/config.mk | 1 - source4/smb_server/smb2/config.mk | 1 - 2 files changed, 2 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb/config.mk b/source4/smb_server/smb/config.mk index ddadc29ddb..7927f295b9 100644 --- a/source4/smb_server/smb/config.mk +++ b/source4/smb_server/smb/config.mk @@ -16,6 +16,5 @@ OBJ_FILES = \ signing.o PUBLIC_DEPENDENCIES = \ ntvfs LIBPACKET CREDENTIALS -LDFLAGS = $(SMB_SERVER_OUTPUT) # End SUBSYSTEM SMB_PROTOCOL ####################### diff --git a/source4/smb_server/smb2/config.mk b/source4/smb_server/smb2/config.mk index b7d7cdc282..d5ba43b3a8 100644 --- a/source4/smb_server/smb2/config.mk +++ b/source4/smb_server/smb2/config.mk @@ -13,6 +13,5 @@ OBJ_FILES = \ keepalive.o PUBLIC_DEPENDENCIES = \ ntvfs LIBPACKET LIBCLI_SMB2 -LDFLAGS = $(SMB_SERVER_OUTPUT) # End SUBSYSTEM SMB2_PROTOCOL ####################### -- cgit From ff0315ba859421dff6aba055887e086fa68c2951 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Feb 2008 20:04:18 +0100 Subject: Rename include to mkinclude to emphasize it is different from make's include. (This used to be commit 0e1d0a874ae3d22b8f97a79b81fe0af3ef53a771) --- source4/smb_server/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/config.mk b/source4/smb_server/config.mk index f21336ae69..85c969df59 100644 --- a/source4/smb_server/config.mk +++ b/source4/smb_server/config.mk @@ -25,5 +25,5 @@ PUBLIC_DEPENDENCIES = \ # End SUBSYSTEM SMB ####################### -include smb/config.mk -include smb2/config.mk +mkinclude smb/config.mk +mkinclude smb2/config.mk -- cgit