From 40f37838735bd8bc7bf0ddffcf56c84f86f4bc18 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 5 Feb 2010 16:55:15 +0100 Subject: [PATCH 1/9] s3:smbd: rename api_RNetServerEnum => api_RNetServerEnum2 metze (cherry picked from commit dc58672c6588a1715698721153b35ed2d594bc67) --- source3/smbd/lanman.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index b15e685..da09ddb 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -1362,7 +1362,7 @@ static bool srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2) extracted from lists saved by nmbd on the local host. ****************************************************************************/ -static bool api_RNetServerEnum(connection_struct *conn, uint16 vuid, +static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid, char *param, int tpscnt, char *data, int tdscnt, int mdrcnt, int mprcnt, char **rdata, @@ -1507,7 +1507,7 @@ static bool api_RNetServerEnum(connection_struct *conn, uint16 vuid, SAFE_FREE(servers); - DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n", + DEBUG(3,("NetServerEnum2 domain = %s uLevel=%d counted=%d total=%d\n", domain,uLevel,counted,counted+missed)); return True; @@ -4628,7 +4628,7 @@ static const struct { {"WPrintDestGetInfo", RAP_WPrintDestGetInfo, api_WPrintDestGetInfo}, {"NetRemoteTOD", RAP_NetRemoteTOD, api_NetRemoteTOD}, {"WPrintQueuePurge", RAP_WPrintQPurge, api_WPrintQueueCtrl}, - {"NetServerEnum", RAP_NetServerEnum2, api_RNetServerEnum}, /* anon OK */ + {"NetServerEnum2", RAP_NetServerEnum2, api_RNetServerEnum2}, /* anon OK */ {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms}, {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword}, {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon}, -- 1.6.3.3 From b368e8500bd2d81d879f6120c52ff9908ef2dbc0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Feb 2010 18:45:18 +0100 Subject: [PATCH 2/9] s3:smbd: add/improve some DEBUG messages in api_RNetServerEnum2() metze (cherry picked from commit 495ac4616654c9e62e14031b7439aff21e42ec91) --- source3/smbd/lanman.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index da09ddb..61cf5a5 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -1431,6 +1431,8 @@ static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid, fstrcpy(domain, lp_workgroup()); } + DEBUG(4, ("domain [%s]\n", domain)); + if (lp_browse_list()) { total = get_server_info(servertype,&servers,domain); } @@ -1453,8 +1455,8 @@ static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid, } lastname = s->name; data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0); - DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n", - s->name, s->type, s->comment, s->domain)); + DEBUG(4,("fill_srv_info[%d] %20s %8x %25s %15s\n", + i, s->name, s->type, s->comment, s->domain)); if (data_len <= buf_len) { counted++; @@ -1489,8 +1491,8 @@ static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid, } lastname = s->name; fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata); - DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n", - s->name, s->type, s->comment, s->domain)); + DEBUG(4,("fill_srv_info[%d] %20s %8x %25s %15s\n", + i, s->name, s->type, s->comment, s->domain)); count2--; } } -- 1.6.3.3 From a43b7ef80b0960c793a09c79d0d4833d94cd4cac Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Dec 2009 14:35:24 +1100 Subject: [PATCH 3/9] util: added binsearch.h for binary array searches This was moved from the schema_query code. It will now be used in more than one place, so best to make it a library macro. I think there are quite a few places that could benefit from this. (cherry picked from commit 71943e8858943718affb6a3c0ded2127f07057f0) Signed-off-by: Stefan Metzmacher (cherry picked from commit 448b8f35d7a7cff73d35304673302178f593c9d0) Signed-off-by: Stefan Metzmacher --- lib/util/binsearch.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 68 insertions(+), 0 deletions(-) create mode 100644 lib/util/binsearch.h diff --git a/lib/util/binsearch.h b/lib/util/binsearch.h new file mode 100644 index 0000000..ac83990 --- /dev/null +++ b/lib/util/binsearch.h @@ -0,0 +1,68 @@ +/* + Unix SMB/CIFS implementation. + + a generic binary search macro + + Copyright (C) Andrew Tridgell 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _BINSEARCH_H +#define _BINSEARCH_H + +/* a binary array search, where the array is an array of pointers to structures, + and we want to find a match for 'target' on 'field' in those structures. + + Inputs: + array: base pointer to an array of structures + arrray_size: number of elements in the array + field: the name of the field in the structure we are keying off + target: the field value we are looking for + comparison_fn: the comparison function + result: where the result of the search is put + + if the element is found, then 'result' is set to point to the found array element. If not, + then 'result' is set to NULL. + + The array is assumed to be sorted by the same comparison_fn as the + search (with, for example, qsort) + */ +#define BINARY_ARRAY_SEARCH_P(array, array_size, field, target, comparison_fn, result) do { \ + int32_t _b, _e; \ + (result) = NULL; \ + if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ + int32_t _i = (_b+_e)/2; \ + int _r = comparison_fn(target, array[_i]->field); \ + if (_r == 0) { (result) = array[_i]; break; } \ + if (_r < 0) _e = _i - 1; else _b = _i + 1; \ + }} } while (0) + +/* + like BINARY_ARRAY_SEARCH_P, but assumes that the array is an array + of structures, rather than pointers to structures + + result points to the found structure, or NULL + */ +#define BINARY_ARRAY_SEARCH(array, array_size, field, target, comparison_fn, result) do { \ + int32_t _b, _e; \ + (result) = NULL; \ + if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ + int32_t _i = (_b+_e)/2; \ + int _r = comparison_fn(target, array[_i].field); \ + if (_r == 0) { (result) = &array[_i]; break; } \ + if (_r < 0) _e = _i - 1; else _b = _i + 1; \ + }} } while (0) + +#endif -- 1.6.3.3 From 8699af2abd8d1fccf68ead1da9b0ba755cea8041 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Feb 2010 19:07:45 +0100 Subject: [PATCH 4/9] s3:smbd: implement api_RNetServerEnum3 This is needed to support large browse lists. metze (cherry picked from commit 30eec0656c926d3d85a438dc28f17649b53318f8) --- source3/smbd/lanman.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 212 insertions(+), 1 deletions(-) diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 61cf5a5..98c9d75 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -26,6 +26,7 @@ */ #include "includes.h" +#include "../lib/util/binsearch.h" #ifdef CHECK_TYPES #undef CHECK_TYPES @@ -1354,7 +1355,8 @@ static int fill_srv_info(struct srv_info_struct *service, static bool srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2) { - return(strcmp(s1->name,s2->name)); +#undef strcasecmp + return strcasecmp(s1->name,s2->name); } /**************************************************************************** @@ -1515,6 +1517,214 @@ static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid, return True; } +static bool srv_name_match(const char *n1, const char *n2) +{ + /* + * [MS-RAP] footnote <88> for Section 3.2.5.15 says: + * + * In Windows, FirstNameToReturn need not be an exact match: + * the server will return a list of servers that exist on + * the network greater than or equal to the FirstNameToReturn. + */ + int ret = strcasecmp(n1, n2); + + if (ret <= 0) { + return 0; + } + + return ret; +} + +static bool api_RNetServerEnum3(connection_struct *conn, uint16 vuid, + char *param, int tpscnt, + char *data, int tdscnt, + int mdrcnt, int mprcnt, char **rdata, + char **rparam, int *rdata_len, int *rparam_len) +{ + char *str1 = get_safe_str_ptr(param, tpscnt, param, 2); + char *str2 = skip_string(param,tpscnt,str1); + char *p = skip_string(param,tpscnt,str2); + int uLevel = get_safe_SVAL(param, tpscnt, p, 0, -1); + int buf_len = get_safe_SVAL(param,tpscnt, p, 2, 0); + uint32 servertype = get_safe_IVAL(param,tpscnt,p,4, 0); + char *p2; + int data_len, fixed_len, string_len; + int f_len = 0, s_len = 0; + struct srv_info_struct *servers=NULL; + int counted=0,first=0,total=0; + int i,missed; + fstring domain; + fstring first_name; + bool domain_request; + bool local_request; + + if (!str1 || !str2 || !p) { + return False; + } + + /* If someone sets all the bits they don't really mean to set + DOMAIN_ENUM and LOCAL_LIST_ONLY, they just want all the + known servers. */ + + if (servertype == SV_TYPE_ALL) { + servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY); + } + + /* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set + any other bit (they may just set this bit on its own) they + want all the locally seen servers. However this bit can be + set on its own so set the requested servers to be + ALL - DOMAIN_ENUM. */ + + if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM)) { + servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM); + } + + domain_request = ((servertype & SV_TYPE_DOMAIN_ENUM) != 0); + local_request = ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0); + + p += 8; + + if (strcmp(str1, "WrLehDzz") != 0) { + return false; + } + if (!check_server_info(uLevel,str2)) { + return False; + } + + DEBUG(4, ("server request level: %s %8x ", str2, servertype)); + DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request))); + DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request))); + + if (skip_string(param,tpscnt,p) == NULL) { + return False; + } + pull_ascii_fstring(domain, p); + if (domain[0] == '\0') { + fstrcpy(domain, lp_workgroup()); + } + p = skip_string(param,tpscnt,p); + if (skip_string(param,tpscnt,p) == NULL) { + return False; + } + pull_ascii_fstring(first_name, p); + + DEBUG(4, ("domain: '%s' first_name: '%s'\n", + domain, first_name)); + + if (lp_browse_list()) { + total = get_server_info(servertype,&servers,domain); + } + + data_len = fixed_len = string_len = 0; + missed = 0; + + if (total > 0) { + qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp); + } + + if (first_name[0] != '\0') { + struct srv_info_struct *first_server = NULL; + + BINARY_ARRAY_SEARCH(servers, total, name, first_name, + srv_name_match, first_server); + if (first_server) { + first = PTR_DIFF(first_server, servers) / sizeof(*servers); + /* + * The binary search may not find the exact match + * so we need to search backward to find the first match + * + * This implements the strange matching windows + * implements. (see the comment in srv_name_match(). + */ + for (;first > 0;) { + int ret; + ret = strcasecmp(first_name, + servers[first-1].name); + if (ret > 0) { + break; + } + first--; + } + } else { + /* we should return no entries */ + first = total; + } + } + + { + char *lastname=NULL; + + for (i=first;iname)) { + continue; + } + lastname = s->name; + data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0); + DEBUG(4,("fill_srv_info[%d] %20s %8x %25s %15s\n", + i, s->name, s->type, s->comment, s->domain)); + + if (data_len <= buf_len) { + counted++; + fixed_len += f_len; + string_len += s_len; + } else { + missed++; + } + } + } + + *rdata_len = fixed_len + string_len; + *rdata = smb_realloc_limit(*rdata,*rdata_len); + if (!*rdata) { + return False; + } + + p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */ + p = *rdata; + f_len = fixed_len; + s_len = string_len; + + { + char *lastname=NULL; + int count2 = counted; + + for (i = first; i < total && count2;i++) { + struct srv_info_struct *s = &servers[i]; + + if (lastname && strequal(lastname,s->name)) { + continue; + } + lastname = s->name; + fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata); + DEBUG(4,("fill_srv_info[%d] %20s %8x %25s %15s\n", + i, s->name, s->type, s->comment, s->domain)); + count2--; + } + } + + *rparam_len = 8; + *rparam = smb_realloc_limit(*rparam,*rparam_len); + if (!*rparam) { + return False; + } + SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERRmoredata)); + SSVAL(*rparam,2,0); + SSVAL(*rparam,4,counted); + SSVAL(*rparam,6,counted+missed); + + DEBUG(3,("NetServerEnum3 domain = %s uLevel=%d first=%d[%s => %s] counted=%d total=%d\n", + domain,uLevel,first,first_name, + first < total ? servers[first].name : "", + counted,counted+missed)); + + SAFE_FREE(servers); + + return True; +} + /**************************************************************************** command 0x34 - suspected of being a "Lookup Names" stub api ****************************************************************************/ @@ -4631,6 +4841,7 @@ static const struct { {"NetRemoteTOD", RAP_NetRemoteTOD, api_NetRemoteTOD}, {"WPrintQueuePurge", RAP_WPrintQPurge, api_WPrintQueueCtrl}, {"NetServerEnum2", RAP_NetServerEnum2, api_RNetServerEnum2}, /* anon OK */ + {"NetServerEnum3", RAP_NetServerEnum3, api_RNetServerEnum3}, /* anon OK */ {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms}, {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword}, {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon}, -- 1.6.3.3 From 6707e4c8ef5c9d00849305d8673706d831d3db5c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Feb 2010 18:38:03 +0100 Subject: [PATCH 5/9] s3:libsmb: fix NetServerEnum3 rap calls. metze (cherry picked from commit 9b5198dd443a00fdad4faa1f9cdabedd81012d93) --- source3/libsmb/clirap.c | 24 +++++++++++++++++++----- 1 files changed, 19 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 9705cac..36b137e 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -247,11 +247,9 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = param; SIVAL(p,0,func); /* api number */ p += 2; - /* Next time through we need to use the continue api */ - func = RAP_NetServerEnum3; - if (last_entry) { - strlcpy(p,"WrLehDOz", sizeof(param)-PTR_DIFF(p,param)); + if (func == RAP_NetServerEnum3) { + strlcpy(p,"WrLehDzz", sizeof(param)-PTR_DIFF(p,param)); } else { strlcpy(p,"WrLehDz", sizeof(param)-PTR_DIFF(p,param)); } @@ -270,7 +268,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, * to continue from. */ len = push_ascii(p, - last_entry ? last_entry : workgroup, + workgroup, sizeof(param) - PTR_DIFF(p,param) - 1, STR_TERMINATE|STR_UPPER); @@ -280,6 +278,22 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, } p += len; + if (func == RAP_NetServerEnum3) { + len = push_ascii(p, + last_entry ? last_entry : "", + sizeof(param) - PTR_DIFF(p,param) - 1, + STR_TERMINATE); + + if (len == (size_t)-1) { + SAFE_FREE(last_entry); + return false; + } + p += len; + } + + /* Next time through we need to use the continue api */ + func = RAP_NetServerEnum3; + if (!cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ -- 1.6.3.3 From d8e8899b341f233e3616a6d2bd2efa938b81f5ee Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 9 Feb 2010 18:54:41 +0100 Subject: [PATCH 6/9] s3:smbd: Fix really ugly bool vs. int bug!!! A comparison function for qsort needs to return an 'int'! Otherwise you'll get random results depending on the compiler and the architecture... metze (cherry picked from commit 1686a5e7e7eb1b411b003cbbde5c0d28741c6d02) --- source3/smbd/lanman.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 98c9d75..5e01235 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -1353,7 +1353,7 @@ static int fill_srv_info(struct srv_info_struct *service, } -static bool srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2) +static int srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2) { #undef strcasecmp return strcasecmp(s1->name,s2->name); @@ -1517,7 +1517,7 @@ static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid, return True; } -static bool srv_name_match(const char *n1, const char *n2) +static int srv_name_match(const char *n1, const char *n2) { /* * [MS-RAP] footnote <88> for Section 3.2.5.15 says: -- 1.6.3.3 From cd8efbfaa47dff96de1309e056d26124ffd5051c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 9 Feb 2010 18:58:36 +0100 Subject: [PATCH 7/9] s3:smbd: use StrCaseCmp() instead of strcasecmp metze (cherry picked from commit bc8242a08e1bb9489cc8171b1ec02bd2518b1857) --- source3/smbd/lanman.c | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 5e01235..4e7c945 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -1355,8 +1355,7 @@ static int fill_srv_info(struct srv_info_struct *service, static int srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2) { -#undef strcasecmp - return strcasecmp(s1->name,s2->name); + return StrCaseCmp(s1->name,s2->name); } /**************************************************************************** @@ -1526,7 +1525,7 @@ static int srv_name_match(const char *n1, const char *n2) * the server will return a list of servers that exist on * the network greater than or equal to the FirstNameToReturn. */ - int ret = strcasecmp(n1, n2); + int ret = StrCaseCmp(n1, n2); if (ret <= 0) { return 0; @@ -1639,7 +1638,7 @@ static bool api_RNetServerEnum3(connection_struct *conn, uint16 vuid, */ for (;first > 0;) { int ret; - ret = strcasecmp(first_name, + ret = StrCaseCmp(first_name, servers[first-1].name); if (ret > 0) { break; -- 1.6.3.3 From 7f5d9a0f99638b3cb0bd90c7e5c0611d7177aa94 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Feb 2010 12:17:08 -0800 Subject: [PATCH 8/9] Fix off-by-one error in working out the limit of the NetServerEnum comment. Jeremy. (cherry picked from commit 9ad6f432f3f5844b4b419e7cbaf3c3e70b052d29) Signed-off-by: Stefan Metzmacher --- source3/libsmb/clirap.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 36b137e..2abb550 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -366,7 +366,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, comment_offset = (IVAL(p,22) & 0xFFFF)-converter; cmnt = comment_offset?(rdata+comment_offset):""; - if (comment_offset < 0 || comment_offset > (int)rdrcnt) { + if (comment_offset < 0 || comment_offset >= (int)rdrcnt) { TALLOC_FREE(frame); continue; } -- 1.6.3.3 From 08a649643b3b4c778c7d7f60ac0cdee7fb56ad93 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Feb 2010 15:14:38 -0800 Subject: [PATCH 9/9] Fix bug #7122 - Reading a large browselist fails (server returns invalid values in subsequent SMBtrans replies) There are two problems: 1). The server is off-by-one in the end of buffer space test. 2). The server returns 0 in the totaldata (smb_vwv1) and totalparams (smb_vwv0) fields in the second and subsequent SMBtrans replies. This patch fixes both. Jeremy. (cherry picked from commit 8ddc977c1421a47bedba8d5494f7ae67692b772a) Signed-off-by: Stefan Metzmacher --- source3/smbd/ipc.c | 3 +++ source3/smbd/lanman.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 5fd756e..2cf0038 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -170,6 +170,9 @@ void send_trans_reply(connection_struct *conn, rparam, tot_param_sent, this_lparam, rdata, tot_data_sent, this_ldata); + SSVAL(req->outbuf,smb_vwv0,lparam); + SSVAL(req->outbuf,smb_vwv1,ldata); + SSVAL(req->outbuf,smb_vwv3,this_lparam); SSVAL(req->outbuf,smb_vwv4, smb_offset(smb_buf(req->outbuf)+1,req->outbuf)); diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 4e7c945..40b6aca 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -1459,7 +1459,7 @@ static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid, DEBUG(4,("fill_srv_info[%d] %20s %8x %25s %15s\n", i, s->name, s->type, s->comment, s->domain)); - if (data_len <= buf_len) { + if (data_len < buf_len) { counted++; fixed_len += f_len; string_len += s_len; @@ -1665,7 +1665,7 @@ static bool api_RNetServerEnum3(connection_struct *conn, uint16 vuid, DEBUG(4,("fill_srv_info[%d] %20s %8x %25s %15s\n", i, s->name, s->type, s->comment, s->domain)); - if (data_len <= buf_len) { + if (data_len < buf_len) { counted++; fixed_len += f_len; string_len += s_len; @@ -2030,7 +2030,7 @@ static bool api_RNetShareEnum( connection_struct *conn, uint16 vuid, if( lp_browseable( i ) && lp_snum_ok( i ) && (strlen(servicename_dos) < 13)) { total++; data_len += fill_share_info(conn,i,uLevel,0,&f_len,0,&s_len,0); - if (data_len <= buf_len) { + if (data_len < buf_len) { counted++; fixed_len += f_len; string_len += s_len; -- 1.6.3.3