summaryrefslogtreecommitdiff
path: root/source4/smb_server/smb/negprot.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2006-03-06 13:22:16 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:52:17 -0500
commit1bff329dff79ca7dacc7e60068233462689fa3f7 (patch)
tree0ea01a8107f3182b853cd751551ad622ba8f94a6 /source4/smb_server/smb/negprot.c
parent98aa64fa343718f3f40bb724b838723d5752701b (diff)
downloadsamba-1bff329dff79ca7dacc7e60068233462689fa3f7.tar.gz
samba-1bff329dff79ca7dacc7e60068233462689fa3f7.tar.bz2
samba-1bff329dff79ca7dacc7e60068233462689fa3f7.zip
r13858: - use req_pull_ascii4() instead of doing strlen() on client provided buffers
- also terminate the connection if we don't support any protocol the client provides metze (This used to be commit 7f2a6cfd6f9c01d1ff40d35346aba678a7ba77f2)
Diffstat (limited to 'source4/smb_server/smb/negprot.c')
-rw-r--r--source4/smb_server/smb/negprot.c64
1 files changed, 34 insertions, 30 deletions
diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c
index 6bac657e8c..b2f136f4f7 100644
--- a/source4/smb_server/smb/negprot.c
+++ b/source4/smb_server/smb/negprot.c
@@ -443,10 +443,10 @@ static const struct {
void reply_negprot(struct smbsrv_request *req)
{
- int Index=0;
- int choice = -1;
int protocol;
uint8_t *p;
+ uint32_t protos_count = 0;
+ char **protos = NULL;
if (req->smb_conn->negotiate.done_negprot) {
smbsrv_terminate_connection(req->smb_conn, "multiple negprot's are not permitted");
@@ -454,37 +454,41 @@ void reply_negprot(struct smbsrv_request *req)
}
req->smb_conn->negotiate.done_negprot = True;
- p = req->in.data + 1;
+ p = req->in.data;
+ while (True) {
+ size_t len;
- while (p < req->in.data + req->in.data_size) {
- Index++;
- DEBUG(3,("Requested protocol [%s]\n",(const char *)p));
- p += strlen((const char *)p) + 2;
+ protos = talloc_realloc(req, protos, char *, protos_count + 1);
+ if (!protos) {
+ smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_NO_MEMORY));
+ return;
+ }
+ protos[protos_count] = NULL;
+ len = req_pull_ascii4(req, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE);
+ p += len;
+ if (len == 0 || !protos[protos_count]) break;
+
+ DEBUG(3,("Requested protocol [%d][%s]\n", protos_count, protos[protos_count]));
+ protos_count++;
}
-
+
/* Check for protocols, most desirable first */
for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
- p = req->in.data+1;
- Index = 0;
- if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
- (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
- while (p < (req->in.data + req->in.data_size)) {
- if (strequal((const char *)p,supported_protocols[protocol].proto_name))
- choice = Index;
- Index++;
- p += strlen((const char *)p) + 2;
- }
- if(choice != -1)
- break;
- }
-
- if(choice != -1) {
- sub_set_remote_proto(supported_protocols[protocol].short_name);
- supported_protocols[protocol].proto_reply_fn(req, choice);
- DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
- } else {
- DEBUG(0,("No protocol supported !\n"));
+ int i;
+
+ if (supported_protocols[protocol].protocol_level > lp_maxprotocol()) continue;
+ if (supported_protocols[protocol].protocol_level < lp_minprotocol()) continue;
+
+ for (i = 0; i < protos_count; i++) {
+ if (strcmp(supported_protocols[protocol].proto_name, protos[i]) != 0) continue;
+
+ supported_protocols[protocol].proto_reply_fn(req, i);
+ sub_set_remote_proto(supported_protocols[protocol].short_name);
+ DEBUG(3,("Selected protocol [%d][%s]\n",
+ i, supported_protocols[protocol].proto_name));
+ return;
+ }
}
-
- DEBUG(5,("negprot index=%d\n", choice));
+
+ smbsrv_terminate_connection(req->smb_conn, "No protocol supported !");
}