From de1c9f1f6d36282fc6d1a7f25a7d79b74a081160 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Jul 2007 11:08:43 +0000 Subject: r24001: Separate out the parsing of the client's requested protocols This way the range checking only needs to be done once (This used to be commit befaa9713adec90088eedcf264f1e396ab150d25) --- source3/smbd/negprot.c | 95 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 29 deletions(-) diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index 4a9492a766..4e3d8f1b3e 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -481,16 +481,17 @@ static const struct { ****************************************************************************/ int reply_negprot(connection_struct *conn, - char *inbuf,char *outbuf, int dum_size, + char *inbuf,char *outbuf, int size, int dum_buffsize) { int outsize = set_message(inbuf,outbuf,1,0,True); - int Index=0; int choice= -1; int protocol; char *p; - int bcc = SVAL(smb_buf(inbuf),-2); int arch = ARCH_ALL; + int num_cliprotos; + char **cliprotos; + int i; static BOOL done_negprot = False; @@ -502,41 +503,78 @@ int reply_negprot(connection_struct *conn, } done_negprot = True; + if (inbuf[size-1] != '\0') { + DEBUG(0, ("negprot protocols not 0-terminated\n")); + END_PROFILE(SMBnegprot); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + p = smb_buf(inbuf)+1; - while (p < (smb_buf(inbuf) + bcc)) { - Index++; - DEBUG(3,("Requested protocol [%s]\n",p)); - if (strcsequal(p,"Windows for Workgroups 3.1a")) - arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K ); - else if (strcsequal(p,"DOS LM1.2X002")) + + num_cliprotos = 0; + cliprotos = NULL; + + while (smb_bufrem(inbuf, p) > 0) { + char **tmp; + + tmp = TALLOC_REALLOC_ARRAY(tmp_talloc_ctx(), cliprotos, char *, + num_cliprotos+1); + if (tmp == NULL) { + DEBUG(0, ("talloc failed\n")); + TALLOC_FREE(cliprotos); + END_PROFILE(SMBnegprot); + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + + cliprotos = tmp; + + if (pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p) + == (size_t)-1) { + DEBUG(0, ("pull_ascii_talloc failed\n")); + TALLOC_FREE(cliprotos); + END_PROFILE(SMBnegprot); + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + + DEBUG(3, ("Requested protocol [%s]\n", + cliprotos[num_cliprotos])); + + num_cliprotos += 1; + p += strlen(p) + 2; + } + + for (i=0; i= lp_minprotocol())) - while (p < (smb_buf(inbuf) + bcc)) { - if (strequal(p,supported_protocols[protocol].proto_name)) - choice = Index; - Index++; - p += strlen(p) + 2; + while (i < num_cliprotos) { + if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) + choice = i; + i++; } if(choice != -1) break; @@ -620,6 +656,7 @@ int reply_negprot(connection_struct *conn, "client negotiated a downlevel protocol"); } + TALLOC_FREE(cliprotos); END_PROFILE(SMBnegprot); return(outsize); } -- cgit