The Samba-Bugzilla – Attachment 5298 Details for
Bug 7119
support for large browselist
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for v3-5
tmp.diff (text/plain), 16.47 KB, created by
Stefan Metzmacher
on 2010-02-08 12:23:47 UTC
(
hide
)
Description:
Patch for v3-5
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2010-02-08 12:23:47 UTC
Size:
16.47 KB
patch
obsolete
>From 549d61b02c0dd1b2e4169ff1b1d7b8afb2a8cf94 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 5 Feb 2010 16:55:15 +0100 >Subject: [PATCH 1/5] 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 95b21c9..01f3299 100644 >--- a/source3/smbd/lanman.c >+++ b/source3/smbd/lanman.c >@@ -1360,7 +1360,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, >@@ -1505,7 +1505,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; >@@ -4631,7 +4631,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 b01ad8f78eab930697d94a3f8abb5928b41a9d21 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 8 Feb 2010 18:45:18 +0100 >Subject: [PATCH 2/5] 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 01f3299..bd67739 100644 >--- a/source3/smbd/lanman.c >+++ b/source3/smbd/lanman.c >@@ -1429,6 +1429,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); > } >@@ -1451,8 +1453,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++; >@@ -1487,8 +1489,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 b710fab9ace179185b15409bcc5d4994f7ee8ca2 Mon Sep 17 00:00:00 2001 >From: Andrew Tridgell <tridge@samba.org> >Date: Thu, 10 Dec 2009 14:35:24 +1100 >Subject: [PATCH 3/5] 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 <metze@samba.org> >(cherry picked from commit 448b8f35d7a7cff73d35304673302178f593c9d0) > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 6b24639c08b764eb0205c63674e80b303b2be2ac) > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > 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 <http://www.gnu.org/licenses/>. >+*/ >+ >+#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 4251ce4063e8b5fa4884d27065b1e21bf0d2fa09 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 5 Feb 2010 18:08:46 +0100 >Subject: [PATCH 4/5] 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 bd67739..83f0da4 100644 >--- a/source3/smbd/lanman.c >+++ b/source3/smbd/lanman.c >@@ -29,6 +29,7 @@ > #include "smbd/globals.h" > #include "../librpc/gen_ndr/cli_samr.h" > #include "../librpc/gen_ndr/srv_samr.h" >+#include "../lib/util/binsearch.h" > > #ifdef CHECK_TYPES > #undef CHECK_TYPES >@@ -1352,7 +1353,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); > } > > /**************************************************************************** >@@ -1513,6 +1515,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;i<total;i++) { >+ struct srv_info_struct *s = &servers[i]; >+ >+ if (lastname && strequal(lastname,s->name)) { >+ 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 > ****************************************************************************/ >@@ -4634,6 +4844,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 55a90d682ac8ac88f1af832165fefd05553018bc Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 8 Feb 2010 18:38:03 +0100 >Subject: [PATCH 5/5] 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 3f77378..bccb0f2 100644 >--- a/source3/libsmb/clirap.c >+++ b/source3/libsmb/clirap.c >@@ -248,11 +248,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)); > } >@@ -271,7 +269,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); > >@@ -281,6 +279,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 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
jra
:
review+
Actions:
View
Attachments on
bug 7119
: 5298 |
5302
|
5320
|
5321