The branch, v4-3-test has been updated via ec7f97c ctdb-pmda: Add missing prototype declaration for non-static function via d0c4863 ctdb-daemon: Check if updates are in flight when releasing all IPs via 3c7f3e7 ctdb-banning: If node is already banned, do not run ctdb_local_node_got_banned() via b37340b s3-net: use talloc array in share allowedusers via 0c7e786 s4:torture:vfs_fruit: add a test for stream names via 3c1e7cb s4:torture:vfs_fruit: pass xattr name as arg to torture_setup_local_xattr() via 047cbb3 vfs_catia: run translation on stream names via fe55c949 vfs_streams_xattr: stream names may contain colons via 977be7b python:samba/upgrade.py Fix format string syntax in error condition via 20d00d3 s4:rpc_server/netlogon: Fix for NetApp from 1d3e6b5 WHATSNEW: Add description of improved cross-compilation support
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-3-test - Log ----------------------------------------------------------------- commit ec7f97cb4145d24d2fbc09fa6aff63c5cac6eed4 Author: Amitay Isaacs <ami...@gmail.com> Date: Mon Aug 3 15:36:06 2015 +1000 ctdb-pmda: Add missing prototype declaration for non-static function BUG: https://bugzilla.samba.org/show_bug.cgi?id=11434 Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> (cherry picked from commit 6538ba5243a043bc727039a16a7a9d5d8027fa06) Autobuild-User(v4-3-test): Stefan Metzmacher <me...@samba.org> Autobuild-Date(v4-3-test): Mon Aug 17 21:14:21 CEST 2015 on sn-devel-104 commit d0c48632d2268ac2978f3ceca0e5215e06d17d25 Author: Martin Schwenke <mar...@meltin.net> Date: Fri Jul 24 15:32:42 2015 +1000 ctdb-daemon: Check if updates are in flight when releasing all IPs Some code involved in releasing IPs is not re-entrant. Memory corruption can occur if, for example, overlapping attempts are made to ban a node. We haven't been able to recreate the corruption but this should protect against it. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11432 Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> (cherry picked from commit 952a50485f68b3cffdf57da84aa9bb9fde630b7e) commit 3c7f3e7b989b1bae03c2f6de18b6359f2f6e313e Author: Amitay Isaacs <ami...@gmail.com> Date: Mon Jul 27 16:51:08 2015 +1000 ctdb-banning: If node is already banned, do not run ctdb_local_node_got_banned() This calls release_all_ips() only once on the first ban. If the node gets banned again due to event script timeout while running release_all_ips(), then avoid calling release_all_ips() in re-entrant fashion. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11432 Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> (cherry picked from commit 8eb04d09b119e234c88150e1dc35fc5057f9c926) commit b37340bc50538b027a4c2804e2b1de574ef03856 Author: Ralph Boehme <s...@samba.org> Date: Tue Aug 4 11:18:34 2015 +0200 s3-net: use talloc array in share allowedusers Bug: https://bugzilla.samba.org/show_bug.cgi?id=11426 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Ralph Böhme <s...@samba.org> Autobuild-Date(master): Tue Aug 4 16:48:36 CEST 2015 on sn-devel-104 (cherry picked from commit 95eb6db580678a29b1f5f30a9567ea449a43d75a) commit 0c7e786cfaf8f06b56042a4fb4dc6a7779bcd53b Author: Ralph Boehme <s...@samba.org> Date: Sun May 10 11:58:32 2015 +0200 s4:torture:vfs_fruit: add a test for stream names Bug: https://bugzilla.samba.org/show_bug.cgi?id=11278 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> (cherry picked from commit 7258061e5e9cd4b68f1c010c3667c3fd2b0663cc) commit 3c1e7cb2244172b12c6bb93598826466f7e1bf5b Author: Ralph Boehme <s...@samba.org> Date: Thu Aug 6 13:48:54 2015 +0200 s4:torture:vfs_fruit: pass xattr name as arg to torture_setup_local_xattr() Bug: https://bugzilla.samba.org/show_bug.cgi?id=11278 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> (cherry picked from commit fe4909f1cab72f80715a996a63290462102aabc6) commit 047cbb35e2b289d46f6f82bab76658114adac51f Author: Ralph Boehme <s...@samba.org> Date: Sat May 9 15:12:41 2015 +0200 vfs_catia: run translation on stream names With vfs_fruit option "fruit:encoding = native" we're already converting stream names that contain illegal NTFS characters from their on-the-wire Unicode Private Range encoding to their native ASCII representation. Unfortunately the reverse mapping for stream names was not perfomed. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11278 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> (cherry picked from commit 1db11998bf1b0eef5f543377700b03ab8739338d) commit fe55c9494b415a22e7de88c0190f9c3fccc2b1ea Author: Ralph Boehme <s...@samba.org> Date: Sat May 9 15:02:03 2015 +0200 vfs_streams_xattr: stream names may contain colons With vfs_fruit option "fruit:encoding = native" we're already converting stream names that contain illegal NTFS characters from their on-the-wire Unicode Private Range encoding to their native ASCII representation. As as result the name of xattrs storing the streams (via vfs_streams_xattr) may contain a colon, so we have to use strrchr_m() instead of strchr_m() for matching the stream type suffix. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11278 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> (cherry picked from commit fb9a64ea37dd4b0cd754fe6d421417a4c8ccbc57) commit 977be7b8e242edeccbecb54e9873ffd6b8151e63 Author: Andrew Bartlett <abart...@samba.org> Date: Fri Aug 14 16:43:41 2015 +1200 python:samba/upgrade.py Fix format string syntax in error condition BUG: https://bugzilla.samba.org/show_bug.cgi?id=11436 Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Martin Schwenke <mar...@meltin.net> Autobuild-User(master): Martin Schwenke <mart...@samba.org> Autobuild-Date(master): Fri Aug 14 10:52:39 CEST 2015 on sn-devel-104 (cherry picked from commit a431828460a8b069589662ad87e47c61c020eb9c) commit 20d00d3b1033bb595c9f4708607dfef2a61ca99c Author: Arvid Requate <requ...@univention.de> Date: Thu Aug 6 15:00:25 2015 +0200 s4:rpc_server/netlogon: Fix for NetApp This patch fixes an issue where NetApp filers joined to a Samba/ADDC cannot resolve SIDs. Without this patch the issue can only be avoided by setting "allow nt4 crypto = yes" in smb.conf. The issue is triggered by NetApp filers in three steps: 1. The client calls netr_ServerReqChallenge to set up challenge tokens 2. Next it calls netr_ServerAuthenticate2 with NETLOGON_NEG_STRONG_KEYS set to 0. Native AD and Samba respond to this with NT_STATUS_DOWNGRADE_DETECTED. At this point Samba throws away the challenge token negotiated in the first step. 3. Next the client calls netr_ServerAuthenticate2 again, this time with NETLOGON_NEG_STRONG_KEYS set to 1. Samba returns NT_STATUS_ACCESS_DENIED as it has lost track of the challenge and denies logon with the message No challenge requested by client [CLNT1/CLNT1$], cannot authenticate Git commit 321ebc99b5a00f82265aee741a48aa84b214d6e8 introduced a workaround for a different but related issue. This patch makes a minor adjustment to that commit to delay flushing the cached challenge until it's clear that we are not in a NT_STATUS_DOWNGRADE_DETECTED situation. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11291 Signed-off-by: Arvid Requate <requ...@univention.de> Reviewed-by: Jeremy Allison <j...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Thu Aug 6 20:29:04 CEST 2015 on sn-devel-104 (cherry picked from commit d3ac3da98611e665dc0f4e825faa5f12f6c848ef) ----------------------------------------------------------------------- Summary of changes: ctdb/server/ctdb_banning.c | 7 +- ctdb/server/ctdb_takeover.c | 18 +++- ctdb/utils/pmda/pmda_ctdb.c | 3 +- python/samba/upgrade.py | 2 +- selftest/target/Samba3.pm | 3 +- selftest/target/Samba4.pm | 3 +- source3/modules/vfs_catia.c | 58 ++++++++++- source3/modules/vfs_streams_xattr.c | 16 ++- source3/utils/net_rpc.c | 24 ++++- source4/rpc_server/netlogon/dcerpc_netlogon.c | 22 ++-- source4/torture/vfs/fruit.c | 143 +++++++++++++++++++++++++- 11 files changed, 270 insertions(+), 29 deletions(-) Changeset truncated at 500 lines: diff --git a/ctdb/server/ctdb_banning.c b/ctdb/server/ctdb_banning.c index a9d1891..d8f7ab1 100644 --- a/ctdb/server/ctdb_banning.c +++ b/ctdb/server/ctdb_banning.c @@ -80,6 +80,7 @@ void ctdb_local_node_got_banned(struct ctdb_context *ctdb) int32_t ctdb_control_set_ban_state(struct ctdb_context *ctdb, TDB_DATA indata) { struct ctdb_ban_time *bantime = (struct ctdb_ban_time *)indata.dptr; + bool already_banned; DEBUG(DEBUG_INFO,("SET BAN STATE\n")); @@ -107,9 +108,11 @@ int32_t ctdb_control_set_ban_state(struct ctdb_context *ctdb, TDB_DATA indata) return 0; } + already_banned = false; if (ctdb->banning_ctx != NULL) { talloc_free(ctdb->banning_ctx); ctdb->banning_ctx = NULL; + already_banned = true; } if (bantime->time == 0) { @@ -136,7 +139,9 @@ int32_t ctdb_control_set_ban_state(struct ctdb_context *ctdb, TDB_DATA indata) event_add_timed(ctdb->ev, ctdb->banning_ctx, timeval_current_ofs(bantime->time,0), ctdb_ban_node_event, ctdb); - ctdb_local_node_got_banned(ctdb); + if (!already_banned) { + ctdb_local_node_got_banned(ctdb); + } return 0; } diff --git a/ctdb/server/ctdb_takeover.c b/ctdb/server/ctdb_takeover.c index d5d2b39..efc80b1 100644 --- a/ctdb/server/ctdb_takeover.c +++ b/ctdb/server/ctdb_takeover.c @@ -3128,9 +3128,6 @@ void ctdb_takeover_client_destructor_hook(struct ctdb_client *client) } -/* - release all IPs on shutdown - */ void ctdb_release_all_ips(struct ctdb_context *ctdb) { struct ctdb_vnn *vnn; @@ -3149,6 +3146,20 @@ void ctdb_release_all_ips(struct ctdb_context *ctdb) continue; } + /* Don't allow multiple releases at once. Some code, + * particularly ctdb_tickle_sentenced_connections() is + * not re-entrant */ + if (vnn->update_in_flight) { + DEBUG(DEBUG_WARNING, + (__location__ + " Not releasing IP %s/%u on interface %s, an update is already in progess\n", + ctdb_addr_to_str(&vnn->public_address), + vnn->public_netmask_bits, + ctdb_vnn_iface_string(vnn))); + continue; + } + vnn->update_in_flight = true; + DEBUG(DEBUG_INFO,("Release of IP %s/%u on interface %s node:-1\n", ctdb_addr_to_str(&vnn->public_address), vnn->public_netmask_bits, @@ -3160,6 +3171,7 @@ void ctdb_release_all_ips(struct ctdb_context *ctdb) vnn->public_netmask_bits); release_kill_clients(ctdb, &vnn->public_address); ctdb_vnn_unassign_iface(ctdb, vnn); + vnn->update_in_flight = false; count++; } diff --git a/ctdb/utils/pmda/pmda_ctdb.c b/ctdb/utils/pmda/pmda_ctdb.c index 2beac8f..1145844 100644 --- a/ctdb/utils/pmda/pmda_ctdb.c +++ b/ctdb/utils/pmda/pmda_ctdb.c @@ -23,7 +23,6 @@ #include <pcp/impl.h> #include <pcp/pmda.h> #include "includes.h" -#include "ctdb.h" #include "ctdb_private.h" #include "ctdb_protocol.h" #include "domain.h" @@ -536,6 +535,8 @@ err_out: return ret; } +void pmda_ctdb_init(pmdaInterface *dp); + /* * Initialise the agent */ diff --git a/python/samba/upgrade.py b/python/samba/upgrade.py index 94b7732..215ccd3 100644 --- a/python/samba/upgrade.py +++ b/python/samba/upgrade.py @@ -407,7 +407,7 @@ def get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, user, attr): expression=("(&(objectClass=posixAccount)(uid=%s))" % (user)), attrs=[attr]) except ldb.LdbError, e: - raise ProvisioningError("Failed to retrieve attribute %s for user %s, the error is: %s", attr, user, e) + raise ProvisioningError("Failed to retrieve attribute %s for user %s, the error is: %s" % (attr, user, e)) else: if msg.count <= 1: # This will raise KeyError (which is what we want) if there isn't a entry for this user diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 9af8faa..d48dbec 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1446,7 +1446,8 @@ sub provision($$$$$$$$) [vfs_fruit] path = $shrdir - vfs objects = catia fruit streams_xattr + vfs objects = catia fruit streams_xattr acl_xattr + ea support = yes fruit:ressource = file fruit:metadata = netatalk fruit:locking = netatalk diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 8e7ac94..16d4b28 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -1070,7 +1070,8 @@ sub provision($$$$$$$$$$) [vfs_fruit] path = $ctx->{share} - vfs objects = catia fruit streams_xattr + vfs objects = catia fruit streams_xattr acl_xattr + ea support = yes fruit:ressource = file fruit:metadata = netatalk fruit:locking = netatalk diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index f2769a9..f455afd 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -706,11 +706,17 @@ catia_streaminfo(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *path, TALLOC_CTX *mem_ctx, - unsigned int *num_streams, - struct stream_struct **streams) + unsigned int *_num_streams, + struct stream_struct **_streams) { char *mapped_name = NULL; NTSTATUS status; + int i; + unsigned int num_streams = 0; + struct stream_struct *streams = NULL; + + *_num_streams = 0; + *_streams = NULL; status = catia_string_replace_allocate(handle->conn, path, &mapped_name, vfs_translate_to_unix); @@ -720,10 +726,54 @@ catia_streaminfo(struct vfs_handle_struct *handle, } status = SMB_VFS_NEXT_STREAMINFO(handle, fsp, mapped_name, - mem_ctx, num_streams,streams); + mem_ctx, &num_streams, &streams); TALLOC_FREE(mapped_name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - return status; + /* + * Translate stream names just like the base names + */ + for (i = 0; i < num_streams; i++) { + /* + * Strip ":" prefix and ":$DATA" suffix to get a + * "pure" stream name and only translate that. + */ + void *old_ptr = streams[i].name; + char *stream_name = streams[i].name + 1; + char *stream_type = strrchr_m(stream_name, ':'); + + if (stream_type != NULL) { + *stream_type = '\0'; + stream_type += 1; + } + + status = catia_string_replace_allocate(handle->conn, stream_name, + &mapped_name, vfs_translate_to_windows); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(streams); + return status; + } + + if (stream_type != NULL) { + streams[i].name = talloc_asprintf(streams, ":%s:%s", + mapped_name, stream_type); + } else { + streams[i].name = talloc_asprintf(streams, ":%s", + mapped_name); + } + TALLOC_FREE(mapped_name); + TALLOC_FREE(old_ptr); + if (streams[i].name == NULL) { + TALLOC_FREE(streams); + return NT_STATUS_NO_MEMORY; + } + } + + *_num_streams = num_streams; + *_streams = streams; + return NT_STATUS_OK; } static NTSTATUS diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index d149fc8..92bd1c9 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -112,7 +112,21 @@ static NTSTATUS streams_xattr_get_name(vfs_handle_struct *handle, SMB_VFS_HANDLE_GET_DATA(handle, config, struct streams_xattr_config, return NT_STATUS_UNSUCCESSFUL); - stype = strchr_m(stream_name + 1, ':'); + /* + * With vfs_fruit option "fruit:encoding = native" we're + * already converting stream names that contain illegal NTFS + * characters from their on-the-wire Unicode Private Range + * encoding to their native ASCII representation. + * + * As as result the name of xattrs storing the streams (via + * vfs_streams_xattr) may contain a colon, so we have to use + * strrchr_m() instead of strchr_m() for matching the stream + * type suffix. + * + * In check_path_syntax() we've already ensured the streamname + * we got from the client is valid. + */ + stype = strrchr_m(stream_name + 1, ':'); if (stype) { if (strcasecmp_m(stype, ":$DATA") != 0) { diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 6eb27c9..1de08c4 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -4522,10 +4522,25 @@ static struct full_alias *server_aliases; /* * Add an alias to the static list. */ -static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias) +static void push_alias(struct full_alias *alias) { - if (server_aliases == NULL) - server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100); + size_t array_size; + + if (server_aliases == NULL) { + server_aliases = talloc_array(NULL, struct full_alias, 100); + if (server_aliases == NULL) { + smb_panic("talloc_array failed"); + } + } + + array_size = talloc_array_length(server_aliases); + if (array_size == num_server_aliases) { + server_aliases = talloc_realloc(NULL, server_aliases, + struct full_alias, array_size + 100); + if (server_aliases == NULL) { + smb_panic("talloc_realloc failed"); + } + } server_aliases[num_server_aliases] = *alias; num_server_aliases += 1; @@ -4634,7 +4649,7 @@ static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd, sid_compose(&alias.sid, domain_sid, groups->entries[i].idx); - push_alias(mem_ctx, &alias); + push_alias(&alias); } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); @@ -5264,6 +5279,7 @@ static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c, free_user_token(&tokens[i].token); } SAFE_FREE(tokens); + TALLOC_FREE(server_aliases); return nt_status; } diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index b47ccf4..49b5b2f 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -172,17 +172,6 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca } } - /* - * At this point we can cleanup the cache entry, - * if we fail the client needs to call netr_ServerReqChallenge - * again. - * - * Note: this handles global_challenge_table == NULL - * and also a non existing record just fine. - */ - memcache_delete(global_challenge_table, - SINGLETON_CACHE, challenge_key); - server_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT | NETLOGON_NEG_PERSISTENT_SAMREPL | NETLOGON_NEG_ARCFOUR | @@ -229,6 +218,17 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca } /* + * At this point we can cleanup the cache entry, + * if we fail the client needs to call netr_ServerReqChallenge + * again. + * + * Note: this handles global_challenge_table == NULL + * and also a non existing record just fine. + */ + memcache_delete(global_challenge_table, + SINGLETON_CACHE, challenge_key); + + /* * According to Microsoft (see bugid #6099) * Windows 7 looks at the negotiate_flags * returned in this structure *even if the diff --git a/source4/torture/vfs/fruit.c b/source4/torture/vfs/fruit.c index 4de21b2..a74dd7d 100644 --- a/source4/torture/vfs/fruit.c +++ b/source4/torture/vfs/fruit.c @@ -29,6 +29,7 @@ #include "param/param.h" #include "libcli/resolve/resolve.h" #include "MacExtensions.h" +#include "lib/util/tsort.h" #include "torture/torture.h" #include "torture/util.h" @@ -58,6 +59,16 @@ goto done; \ }} while (0) +static int qsort_string(char * const *s1, char * const *s2) +{ + return strcmp(*s1, *s2); +} + +static int qsort_stream(const struct stream_struct * s1, const struct stream_struct *s2) +{ + return strcmp(s1->stream_name.s, s2->stream_name.s); +} + /* * REVIEW: * This is hokey, but what else can we do? @@ -1060,6 +1071,7 @@ static bool write_stream(struct smb2_tree *tree, static bool torture_setup_local_xattr(struct torture_context *tctx, const char *path_option, const char *name, + const char *xattr, const char *metadata, size_t size) { @@ -1076,7 +1088,7 @@ static bool torture_setup_local_xattr(struct torture_context *tctx, path = talloc_asprintf(tctx, "%s/%s", spath, name); - result = setxattr(path, AFPINFO_EA_NETATALK, metadata, size, 0); + result = setxattr(path, xattr, metadata, size, 0); if (result != 0) { ret = false; } @@ -1195,6 +1207,7 @@ static bool test_read_atalk_metadata(struct torture_context *tctx, ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/torture_read_metadata", + AFPINFO_EA_NETATALK, metadata_xattr, sizeof(metadata_xattr)); if (ret == false) { goto done; @@ -2163,6 +2176,133 @@ done: return true; } +static bool check_stream_list(struct smb2_tree *tree, + struct torture_context *tctx, + const char *fname, + int num_exp, + const char **exp, + struct smb2_handle h) +{ + union smb_fileinfo finfo; + NTSTATUS status; + int i; + TALLOC_CTX *tmp_ctx = talloc_new(tctx); + char **exp_sort; + struct stream_struct *stream_sort; + + finfo.generic.level = RAW_FILEINFO_STREAM_INFORMATION; + finfo.generic.in.file.handle = h; + + status = smb2_getinfo_file(tree, tctx, &finfo); + torture_assert_ntstatus_ok(tctx, status, "get stream info"); + + torture_assert_int_equal(tctx, finfo.stream_info.out.num_streams, num_exp, + "stream count"); + + if (num_exp == 0) { + TALLOC_FREE(tmp_ctx); + return true; + } + + exp_sort = talloc_memdup(tmp_ctx, exp, num_exp * sizeof(*exp)); + torture_assert(tctx, exp_sort != NULL, __location__); + + TYPESAFE_QSORT(exp_sort, num_exp, qsort_string); + + stream_sort = talloc_memdup(tmp_ctx, finfo.stream_info.out.streams, + finfo.stream_info.out.num_streams * + sizeof(*stream_sort)); + torture_assert(tctx, stream_sort != NULL, __location__); + + TYPESAFE_QSORT(stream_sort, finfo.stream_info.out.num_streams, qsort_stream); + + for (i=0; i<num_exp; i++) { + torture_comment(tctx, "i[%d] exp[%s] got[%s]\n", + i, exp_sort[i], stream_sort[i].stream_name.s); + torture_assert_str_equal(tctx, stream_sort[i].stream_name.s, exp_sort[i], + "stream name"); + } + + TALLOC_FREE(tmp_ctx); + return true; +} + +/* + test stream names +*/ +static bool test_stream_names(struct torture_context *tctx, + struct smb2_tree *tree, + struct smb2_tree *tree2) +{ + TALLOC_CTX *mem_ctx = talloc_new(tctx); + NTSTATUS status; + struct smb2_create create; + struct smb2_handle h; + const char *fname = BASEDIR "\\stream_names.txt"; + const char *sname1; + bool ret; + /* UTF8 private use are starts at 0xef 0x80 0x80 (0xf000) */ + const char *streams[] = { + ":foo" "\xef\x80\xa2" "bar:$DATA", /* "foo:bar:$DATA" */ + ":bar" "\xef\x80\xa2" "baz:$DATA", /* "bar:baz:$DATA" */ + "::$DATA" + }; + + sname1 = talloc_asprintf(mem_ctx, "%s%s", fname, streams[0]); + + /* clean slate ...*/ + smb2_util_unlink(tree, fname); + smb2_deltree(tree, fname); + smb2_deltree(tree, BASEDIR); + + status = torture_smb2_testdir(tree, BASEDIR, &h); + CHECK_STATUS(status, NT_STATUS_OK); + smb2_util_close(tree, h); + + torture_comment(tctx, "(%s) testing stream names\n", __location__); + ZERO_STRUCT(create); + create.in.desired_access = SEC_FILE_WRITE_DATA; + create.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + create.in.share_access = + NTCREATEX_SHARE_ACCESS_DELETE| + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE; + create.in.create_disposition = NTCREATEX_DISP_CREATE; + create.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS; + create.in.fname = sname1; + + status = smb2_create(tree, mem_ctx, &create); + CHECK_STATUS(status, NT_STATUS_OK); + smb2_util_close(tree, create.out.file.handle); + + ret = torture_setup_local_xattr(tctx, "localdir", BASEDIR "/stream_names.txt", + "user.DosStream.bar:baz:$DATA", + "data", strlen("data")); + CHECK_VALUE(ret, true); + -- Samba Shared Repository