summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/nbt/nbtname.c13
-rw-r--r--source4/smb_server/reply.c48
-rw-r--r--source4/smb_server/smb_server.h4
3 files changed, 57 insertions, 8 deletions
diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c
index 8c46379f0b..0584f55fb1 100644
--- a/source4/libcli/nbt/nbtname.c
+++ b/source4/libcli/nbt/nbtname.c
@@ -63,7 +63,7 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component,
/* its a reserved length field */
return NT_STATUS_BAD_NETWORK_NAME;
}
- if (*offset + len + 2 >= ndr->data_size) {
+ if (*offset + len + 2 > ndr->data_size) {
return NT_STATUS_BAD_NETWORK_NAME;
}
*component = (uint8_t*)talloc_strndup(ndr, &ndr->data[1 + *offset], len);
@@ -309,6 +309,17 @@ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name
(ndr_push_flags_fn_t)ndr_push_nbt_name);
}
+
+/*
+ pull a nbt name from a blob
+*/
+NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name)
+{
+ return ndr_pull_struct_blob(blob, mem_ctx, name,
+ (ndr_pull_flags_fn_t)ndr_pull_nbt_name);
+}
+
+
/*
choose a name to use when calling a server in a NBT session request.
we use heuristics to see if the name we have been given is a IP
diff --git a/source4/smb_server/reply.c b/source4/smb_server/reply.c
index 2dc36a3b65..17dcb8623a 100644
--- a/source4/smb_server/reply.c
+++ b/source4/smb_server/reply.c
@@ -25,6 +25,7 @@
#include "includes.h"
#include "smb_server/smb_server.h"
+#include "libcli/nbt/libnbt.h"
/* useful way of catching wct errors with file and line number */
@@ -2370,6 +2371,41 @@ void reply_sendtxt(struct smbsrv_request *req)
}
+/*
+ parse the called/calling names from session request
+*/
+static NTSTATUS parse_session_request(struct smbsrv_request *req)
+{
+ DATA_BLOB blob;
+ NTSTATUS status;
+
+ blob.data = req->in.buffer + 4;
+ blob.length = ascii_len_n(blob.data, req->in.size - PTR_DIFF(blob.data, req->in.buffer));
+ if (blob.length == 0) return NT_STATUS_BAD_NETWORK_NAME;
+
+ req->smb_conn->negotiate.called_name = talloc(req->smb_conn, struct nbt_name);
+ req->smb_conn->negotiate.calling_name = talloc(req->smb_conn, struct nbt_name);
+ if (req->smb_conn->negotiate.called_name == NULL ||
+ req->smb_conn->negotiate.calling_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = nbt_name_from_blob(req, &blob, req->smb_conn->negotiate.called_name);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ blob.data += blob.length;
+ blob.length = ascii_len_n(blob.data, req->in.size - PTR_DIFF(blob.data, req->in.buffer));
+ if (blob.length == 0) return NT_STATUS_BAD_NETWORK_NAME;
+
+ status = nbt_name_from_blob(req, &blob, req->smb_conn->negotiate.calling_name);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ req->smb_conn->negotiate.done_nbt_session = True;
+
+ return NT_STATUS_OK;
+}
+
+
/****************************************************************************
Reply to a special message - a SMB packet with non zero NBT message type
@@ -2378,7 +2414,7 @@ void reply_special(struct smbsrv_request *req)
{
uint8_t msg_type;
uint8_t *buf = talloc_zero_array(req, uint8_t, 4);
-
+
msg_type = CVAL(req->in.buffer,0);
SIVAL(buf, 0, 0);
@@ -2392,13 +2428,11 @@ void reply_special(struct smbsrv_request *req)
SCVAL(buf,0,0x82);
SCVAL(buf,3,0);
-
- DEBUG(0,("REWRITE: not parsing netbios names in NBT session request!\n"));
- /* TODO: store the name for the session setup 'remote
- machine' code, as well as smbstatus */
- req->smb_conn->negotiate.done_nbt_session = True;
-
+ /* we don't check the status - samba always accepts session
+ requests for any name */
+ parse_session_request(req);
+
req->out.buffer = buf;
req->out.size = 4;
req_send_reply_nosign(req);
diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h
index aebace9ad0..2b1ca87cb9 100644
--- a/source4/smb_server/smb_server.h
+++ b/source4/smb_server/smb_server.h
@@ -197,6 +197,10 @@ struct smbsrv_connection {
/* the timezone we sent to the client */
int zone_offset;
+
+ /* NBT names only set when done_nbt_session is true */
+ struct nbt_name *called_name;
+ struct nbt_name *calling_name;
} negotiate;
/* the context associated with open tree connects on a smb socket */