Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • lts-team/packages/samba
  • thctlo/samba-lintianfix
  • arnaudr/samba
  • jrwren/samba
  • paride/samba
  • athos/samba
  • henrich/samba
  • cnotin/samba
  • mimi89999/samba
  • samba-team/samba
  • ahasenack/samba
  • jrtc27/samba
  • noel/samba
13 results
Show changes
Commits on Source (90)
Showing
with 468 additions and 103 deletions
......@@ -25,7 +25,7 @@
########################################################
SAMBA_VERSION_MAJOR=4
SAMBA_VERSION_MINOR=17
SAMBA_VERSION_RELEASE=10
SAMBA_VERSION_RELEASE=11
########################################################
# If a official release has a serious bug #
......
===============================
Release Notes for Samba 4.17.11
September 07, 2023
===============================
This is the latest stable release of the Samba 4.17 release series.
Changes since 4.17.10
---------------------
o Jeremy Allison <jra@samba.org>
* BUG 15419: Weird filename can cause assert to fail in
openat_pathref_fsp_nosymlink().
* BUG 15420: reply_sesssetup_and_X() can dereference uninitialized tmp
pointer.
* BUG 15430: Missing return in reply_exit_done().
* BUG 15432: TREE_CONNECT without SETUP causes smbd to use uninitialized
pointer.
o Andrew Bartlett <abartlet@samba.org>
* BUG 15401: Improve GetNChanges to address some (but not all "Azure AD
Connect") syncronisation tool looping during the initial user sync phase.
* BUG 15407: Samba replication logs show (null) DN.
* BUG 9959: Windows client join fails if a second container CN=System exists
somewhere.
o Ralph Boehme <slow@samba.org>
* BUG 15342: Spotlight sometimes returns no results on latest macOS.
* BUG 15417: Renaming results in NT_STATUS_SHARING_VIOLATION if previously
attempted to remove the destination.
* BUG 15427: Spotlight results return wrong date in result list.
* BUG 15463: macOS mdfind returns only 50 results.
o Volker Lendecke <vl@samba.org>
* BUG 15346: 2-3min delays at reconnect with smb2_validate_sequence_number:
bad message_id 2.
o Stefan Metzmacher <metze@samba.org>
* BUG 15346: 2-3min delays at reconnect with smb2_validate_sequence_number:
bad message_id 2.
* BUG 15441: samba-tool ntacl get segfault if aio_pthread appended.
* BUG 15446: DCERPC_PKT_CO_CANCEL and DCERPC_PKT_ORPHANED can't be parsed.
o MikeLiu <mikeliu@qnap.com>
* BUG 15453: File doesn't show when user doesn't have permission if
aio_pthread is loaded.
o Noel Power <noel.power@suse.com>
* BUG 15384: net ads lookup (with unspecified realm) fails
* BUG 15435: Regression DFS not working with widelinks = true.
o Arvid Requate <requate@univention.de>
* BUG 9959: Windows client join fails if a second container CN=System exists
somewhere.
o Martin Schwenke <mschwenke@ddn.com>
* BUG 15451: ctdb_killtcp fails to work with --enable-pcap and libpcap ≥
1.9.1.
o Jones Syue <jonessyue@qnap.com>
* BUG 15441: samba-tool ntacl get segfault if aio_pthread appended.
* BUG 15449: mdssvc: Do an early talloc_free() in _mdssvc_open().
#######################################
Reporting bugs & Development Discussion
#######################################
Please discuss this release on the samba-technical mailing list or by
joining the #samba-technical:matrix.org matrix room, or
#samba-technical IRC channel on irc.libera.chat.
If you do report problems then please try to send high quality
feedback. If you don't provide vital information to help us track down
the problem then you will probably be ignored. All bug reports should
be filed under the Samba 4.1 and newer product in the project's Bugzilla
database (https://bugzilla.samba.org/).
======================================================================
== Our Code, Our Bugs, Our Responsibility.
== The Samba Team
======================================================================
Release notes for older releases follow:
----------------------------------------
===============================
Release Notes for Samba 4.17.10
July 19, 2023
......@@ -70,8 +159,7 @@ database (https://bugzilla.samba.org/).
======================================================================
Release notes for older releases follow:
----------------------------------------
----------------------------------------------------------------------
==============================
Release Notes for Samba 4.17.9
July 06, 2023
......
......@@ -747,13 +747,6 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
return 0;
}
/*
* Packet capture
*
* If AF_PACKET is available then use a raw socket otherwise use pcap.
* wscript has checked to make sure that pcap is available if needed.
*/
static int tcp4_extract(const uint8_t *ip_pkt,
size_t pktlen,
struct sockaddr_in *src,
......@@ -864,8 +857,14 @@ static int tcp6_extract(const uint8_t *ip_pkt,
return 0;
}
/*
* Packet capture
*
* If AF_PACKET is available then use a raw socket otherwise use pcap.
* wscript has checked to make sure that pcap is available if needed.
*/
#ifdef HAVE_AF_PACKET
#if defined(HAVE_AF_PACKET) && !defined(ENABLE_PCAP)
/*
* This function is used to open a raw socket to capture from
......@@ -881,7 +880,7 @@ int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
return -1;
}
DBG_DEBUG("Created RAW SOCKET FD:%d for tcp tickle\n", s);
DBG_DEBUG("Opened raw socket for TCP tickle capture (fd=%d)\n", s);
ret = set_blocking(s, false);
if (ret != 0) {
......@@ -964,22 +963,92 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
return ENOMSG;
}
#else /* HAVE_AF_PACKET */
#else /* defined(HAVE_AF_PACKET) && !defined(ENABLE_PCAP) */
#include <pcap.h>
/*
* Assume this exists if pcap.h exists - it has been around for a
* while
*/
#include <pcap/sll.h>
int ctdb_sys_open_capture_socket(const char *iface, void **private_data)
{
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *pt;
int pcap_packet_type;
const char *t = NULL;
int fd;
int ret;
pt=pcap_open_live(iface, 100, 0, 0, NULL);
pt = pcap_create(iface, errbuf);
if (pt == NULL) {
DBG_ERR("Failed to open capture device %s\n", iface);
DBG_ERR("Failed to open pcap capture device %s (%s)\n",
iface,
errbuf);
return -1;
}
/*
* pcap isn't very clear about defaults...
*/
ret = pcap_set_snaplen(pt, 100);
if (ret < 0) {
DBG_ERR("Failed to set snaplen for pcap capture\n");
goto fail;
}
ret = pcap_set_promisc(pt, 0);
if (ret < 0) {
DBG_ERR("Failed to unset promiscuous mode for pcap capture\n");
goto fail;
}
ret = pcap_set_timeout(pt, 0);
if (ret < 0) {
DBG_ERR("Failed to set timeout for pcap capture\n");
goto fail;
}
#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
ret = pcap_set_immediate_mode(pt, 1);
if (ret < 0) {
DBG_ERR("Failed to set immediate mode for pcap capture\n");
goto fail;
}
#endif
ret = pcap_activate(pt);
if (ret < 0) {
DBG_ERR("Failed to activate pcap capture\n");
goto fail;
}
pcap_packet_type = pcap_datalink(pt);
switch (pcap_packet_type) {
case DLT_EN10MB:
t = "DLT_EN10MB";
break;
case DLT_LINUX_SLL:
t = "DLT_LINUX_SLL";
break;
#ifdef DLT_LINUX_SLL2
case DLT_LINUX_SLL2:
t = "DLT_LINUX_SLL2";
break;
#endif /* DLT_LINUX_SLL2 */
default:
DBG_ERR("Unknown pcap packet type %d\n", pcap_packet_type);
goto fail;
}
fd = pcap_get_selectable_fd(pt);
DBG_DEBUG("Opened pcap capture for TCP tickle (type=%s, fd=%d)\n",
t,
fd);
*((pcap_t **)private_data) = pt;
return fd;
return pcap_fileno(pt);
fail:
pcap_close(pt);
return -1;
}
int ctdb_sys_close_capture_socket(void *private_data)
......@@ -999,10 +1068,12 @@ int ctdb_sys_read_tcp_packet(int s,
uint16_t *window)
{
int ret;
struct ether_header *eth;
struct pcap_pkthdr pkthdr;
const u_char *buffer;
pcap_t *pt = (pcap_t *)private_data;
int pcap_packet_type;
uint16_t ether_type;
size_t ll_hdr_len;
buffer=pcap_next(pt, &pkthdr);
if (buffer==NULL) {
......@@ -1012,36 +1083,86 @@ int ctdb_sys_read_tcp_packet(int s,
ZERO_STRUCTP(src);
ZERO_STRUCTP(dst);
/* Ethernet */
eth = (struct ether_header *)buffer;
pcap_packet_type = pcap_datalink(pt);
switch (pcap_packet_type) {
case DLT_EN10MB: {
const struct ether_header *eth =
(const struct ether_header *)buffer;
ether_type = ntohs(eth->ether_type);
ll_hdr_len = sizeof(struct ether_header);
break;
}
case DLT_LINUX_SLL: {
const struct sll_header *sll =
(const struct sll_header *)buffer;
uint16_t arphrd_type = ntohs(sll->sll_hatype);
switch (arphrd_type) {
case ARPHRD_ETHER:
case ARPHRD_INFINIBAND:
break;
default:
DBG_DEBUG("SLL: Unknown arphrd_type %"PRIu16"\n",
arphrd_type);
return EPROTONOSUPPORT;
}
ether_type = ntohs(sll->sll_protocol);
ll_hdr_len = SLL_HDR_LEN;
break;
}
#ifdef DLT_LINUX_SLL2
case DLT_LINUX_SLL2: {
const struct sll2_header *sll2 =
(const struct sll2_header *)buffer;
uint16_t arphrd_type = ntohs(sll2->sll2_hatype);
switch (arphrd_type) {
case ARPHRD_ETHER:
case ARPHRD_INFINIBAND:
break;
default:
DBG_DEBUG("SLL2: Unknown arphrd_type %"PRIu16"\n",
arphrd_type);
return EPROTONOSUPPORT;
}
ether_type = ntohs(sll2->sll2_protocol);
ll_hdr_len = SLL2_HDR_LEN;
break;
}
#endif /* DLT_LINUX_SLL2 */
default:
DBG_DEBUG("Unknown pcap packet type %d\n", pcap_packet_type);
return EPROTONOSUPPORT;
}
/* we want either IPv4 or IPv6 */
if (eth->ether_type == htons(ETHERTYPE_IP)) {
ret = tcp4_extract(buffer + sizeof(struct ether_header),
(size_t)(pkthdr.caplen -
sizeof(struct ether_header)),
switch (ether_type) {
case ETHERTYPE_IP:
ret = tcp4_extract(buffer + ll_hdr_len,
(size_t)pkthdr.caplen - ll_hdr_len,
&src->ip,
&dst->ip,
ack_seq,
seq,
rst,
window);
return ret;
} else if (eth->ether_type == htons(ETHERTYPE_IP6)) {
ret = tcp6_extract(buffer + sizeof(struct ether_header),
(size_t)(pkthdr.caplen -
sizeof(struct ether_header)),
break;
case ETHERTYPE_IP6:
ret = tcp6_extract(buffer + ll_hdr_len,
(size_t)pkthdr.caplen - ll_hdr_len,
&src->ip6,
&dst->ip6,
ack_seq,
seq,
rst,
window);
return ret;
break;
case ETHERTYPE_ARP:
/* Silently ignore ARP packets */
return EPROTO;
default:
DBG_DEBUG("Unknown ether type %"PRIu16"\n", ether_type);
return EPROTO;
}
return ENOMSG;
return ret;
}
#endif /* HAVE_AF_PACKET */
#endif /* defined(HAVE_AF_PACKET) && !defined(ENABLE_PCAP) */
......@@ -452,8 +452,14 @@ kill_tcp_connections ()
return
fi
if [ -n "$CTDB_KILLTCP_DEBUGLEVEL" ]; then
_debuglevel="$CTDB_KILLTCP_DEBUGLEVEL"
else
_debuglevel="$CTDB_DEBUGLEVEL"
fi
echo "$_connections" | \
"${CTDB_HELPER_BINDIR}/ctdb_killtcp" "$_iface" || {
CTDB_DEBUGLEVEL="$_debuglevel" \
"${CTDB_HELPER_BINDIR}/ctdb_killtcp" "$_iface" || {
echo "Failed to kill TCP connections"
return
}
......
......@@ -169,17 +169,18 @@ static void reset_connections_capture_tcp_handler(struct tevent_context *ev,
&conn.server, &conn.client,
&ack_seq, &seq, &rst, &window);
if (ret != 0) {
/* probably a non-tcp ACK packet */
/* Not a TCP-ACK? Unexpected protocol? */
DBG_DEBUG("Failed to parse packet, errno=%d\n", ret);
return;
}
if (window == htons(1234) && (rst || seq == 0)) {
/* Ignore packets that we sent! */
D_DEBUG("Ignoring packet: %s, "
"seq=%"PRIu32", ack_seq=%"PRIu32", "
"rst=%d, window=%"PRIu16"\n",
ctdb_connection_to_string(state, &conn, false),
seq, ack_seq, rst, ntohs(window));
DBG_DEBUG("Ignoring sent packet: %s, "
"seq=%"PRIu32", ack_seq=%"PRIu32", "
"rst=%d, window=%"PRIu16"\n",
ctdb_connection_to_string(state, &conn, false),
seq, ack_seq, rst, ntohs(window));
return;
}
......
......@@ -98,6 +98,9 @@ def options(opt):
opt.add_option('--enable-etcd-reclock',
help=("Enable etcd recovery lock helper (default=no)"),
action="store_true", dest='ctdb_etcd_reclock', default=False)
opt.add_option('--enable-pcap',
help=("Use pcap for packet capture (default=no)"),
action="store_true", dest='ctdb_pcap', default=False)
opt.add_option('--with-libcephfs',
help=("Directory under which libcephfs is installed"),
......@@ -201,15 +204,24 @@ def configure(conf):
if not conf.CHECK_VARIABLE('ETIME', headers='errno.h'):
conf.DEFINE('ETIME', 'ETIMEDOUT')
if sys.platform.startswith('linux'):
if Options.options.ctdb_pcap or not sys.platform.startswith('linux'):
conf.DEFINE('ENABLE_PCAP', 1)
if not conf.env.ENABLE_PCAP:
conf.SET_TARGET_TYPE('pcap', 'EMPTY')
else:
conf.find_program('pcap-config', var='PCAP_CONFIG')
if conf.env.PCAP_CONFIG:
conf.CHECK_CFG(path=conf.env.PCAP_CONFIG,
args="--cflags --libs",
package="",
uselib_store="PCAP")
if not conf.CHECK_HEADERS('pcap.h'):
Logs.error('Need libpcap')
sys.exit(1)
if not conf.CHECK_FUNCS_IN('pcap_open_live', 'pcap', headers='pcap.h'):
Logs.error('Need libpcap')
sys.exit(1)
conf.CHECK_FUNCS_IN('pcap_set_immediate_mode', 'pcap', headers='pcap.h')
if not conf.CHECK_FUNCS_IN('backtrace backtrace_symbols', 'execinfo',
checklibc=True, headers='execinfo.h'):
......
......@@ -4220,6 +4220,8 @@ static const struct {
struct smbXcli_negprot_state {
struct smbXcli_conn *conn;
struct tevent_context *ev;
struct smb2_negotiate_contexts *in_ctx;
struct smb2_negotiate_contexts *out_ctx;
uint32_t timeout_msec;
struct {
......@@ -4242,7 +4244,8 @@ struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
uint32_t timeout_msec,
enum protocol_types min_protocol,
enum protocol_types max_protocol,
uint16_t max_credits)
uint16_t max_credits,
struct smb2_negotiate_contexts *in_ctx)
{
struct tevent_req *req, *subreq;
struct smbXcli_negprot_state *state;
......@@ -4254,6 +4257,7 @@ struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
}
state->conn = conn;
state->ev = ev;
state->in_ctx = in_ctx;
state->timeout_msec = timeout_msec;
if (min_protocol == PROTOCOL_NONE) {
......@@ -4934,6 +4938,25 @@ static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_sta
return NULL;
}
if (state->in_ctx != NULL) {
struct smb2_negotiate_contexts *ctxs = state->in_ctx;
for (i=0; i<ctxs->num_contexts; i++) {
struct smb2_negotiate_context *ctx =
&ctxs->contexts[i];
status = smb2_negotiate_context_add(
state,
&c,
ctx->type,
ctx->data.data,
ctx->data.length);
if (!NT_STATUS_IS_OK(status)) {
return NULL;
}
}
}
status = smb2_negotiate_context_push(state, &b, c);
if (!NT_STATUS_IS_OK(status)) {
return NULL;
......@@ -4988,7 +5011,6 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
uint8_t *body;
size_t i;
uint16_t dialect_revision;
struct smb2_negotiate_contexts c = { .num_contexts = 0, };
uint32_t negotiate_context_offset = 0;
uint16_t negotiate_context_count = 0;
DATA_BLOB negotiate_context_blob = data_blob_null;
......@@ -5195,10 +5217,15 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
negotiate_context_blob.data += ctx_ofs;
negotiate_context_blob.length -= ctx_ofs;
status = smb2_negotiate_context_parse(state,
state->out_ctx = talloc_zero(state, struct smb2_negotiate_contexts);
if (tevent_req_nomem(state->out_ctx, req)) {
return;
}
status = smb2_negotiate_context_parse(state->out_ctx,
negotiate_context_blob,
negotiate_context_count,
&c);
state->out_ctx);
if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
status = NT_STATUS_INVALID_NETWORK_RESPONSE;
}
......@@ -5206,8 +5233,8 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
return;
}
preauth = smb2_negotiate_context_find(&c,
SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
preauth = smb2_negotiate_context_find(
state->out_ctx, SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
if (preauth == NULL) {
tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
......@@ -5237,7 +5264,8 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
return;
}
sign_algo = smb2_negotiate_context_find(&c, SMB2_SIGNING_CAPABILITIES);
sign_algo = smb2_negotiate_context_find(
state->out_ctx, SMB2_SIGNING_CAPABILITIES);
if (sign_algo != NULL) {
const struct smb3_signing_capabilities *client_sign_algos =
&state->conn->smb2.client.smb3_capabilities.signing;
......@@ -5296,7 +5324,8 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
conn->smb2.server.sign_algo = sign_algo_selected;
}
cipher = smb2_negotiate_context_find(&c, SMB2_ENCRYPTION_CAPABILITIES);
cipher = smb2_negotiate_context_find(
state->out_ctx, SMB2_ENCRYPTION_CAPABILITIES);
if (cipher != NULL) {
const struct smb3_encryption_capabilities *client_ciphers =
&state->conn->smb2.client.smb3_capabilities.encryption;
......@@ -5516,9 +5545,26 @@ static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
NTSTATUS smbXcli_negprot_recv(struct tevent_req *req)
NTSTATUS smbXcli_negprot_recv(
struct tevent_req *req,
TALLOC_CTX *mem_ctx,
struct smb2_negotiate_contexts **out_ctx)
{
return tevent_req_simple_recv_ntstatus(req);
struct smbXcli_negprot_state *state = tevent_req_data(
req, struct smbXcli_negprot_state);
NTSTATUS status;
if (tevent_req_is_nterror(req, &status)) {
tevent_req_received(req);
return status;
}
if (out_ctx != NULL) {
*out_ctx = talloc_move(mem_ctx, &state->out_ctx);
}
tevent_req_received(req);
return NT_STATUS_OK;
}
NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
......@@ -5543,9 +5589,15 @@ NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
if (ev == NULL) {
goto fail;
}
req = smbXcli_negprot_send(frame, ev, conn, timeout_msec,
min_protocol, max_protocol,
WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
req = smbXcli_negprot_send(
frame,
ev,
conn,
timeout_msec,
min_protocol,
max_protocol,
WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
NULL);
if (req == NULL) {
goto fail;
}
......@@ -5553,7 +5605,7 @@ NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
if (!ok) {
goto fail;
}
status = smbXcli_negprot_recv(req);
status = smbXcli_negprot_recv(req, NULL, NULL);
fail:
TALLOC_FREE(frame);
return status;
......
......@@ -457,14 +457,19 @@ NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
NTSTATUS smb2cli_req_get_sent_iov(struct tevent_req *req,
struct iovec *sent_iov);
struct smb2_negotiate_contexts;
struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct smbXcli_conn *conn,
uint32_t timeout_msec,
enum protocol_types min_protocol,
enum protocol_types max_protocol,
uint16_t max_credits);
NTSTATUS smbXcli_negprot_recv(struct tevent_req *req);
uint16_t max_credits,
struct smb2_negotiate_contexts *in_ctx);
NTSTATUS smbXcli_negprot_recv(
struct tevent_req *req,
TALLOC_CTX *mem_ctx,
struct smb2_negotiate_contexts **out_ctx);
NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
uint32_t timeout_msec,
enum protocol_types min_protocol,
......
......@@ -276,12 +276,10 @@ interface dcerpc
} dcerpc_auth3;
typedef [public] struct {
[value(0)] uint32 _pad;
[flag(NDR_REMAINING)] DATA_BLOB auth_info;
} dcerpc_orphaned;
typedef [public] struct {
[value(0)] uint32 _pad;
[flag(NDR_REMAINING)] DATA_BLOB auth_info;
} dcerpc_co_cancel;
......
......@@ -565,9 +565,14 @@ static int dcerpc_read_ncacn_packet_next_vector(struct tstream_context *stream,
ofs = state->buffer.length;
if (frag_len < ofs) {
if (frag_len <= ofs) {
/*
* something is wrong, let the caller deal with it
* With frag_len == ofs, we are done, this is likely
* a DCERPC_PKT_CO_CANCEL and DCERPC_PKT_ORPHANED
* without any payload.
*
* Otherwise it's a broken packet and we
* let the caller deal with it.
*/
*_vector = NULL;
*_count = 0;
......
......@@ -100,7 +100,7 @@ class MdfindBlackboxTests(BlackboxTestCase):
config = os.environ["SMB_CONF_PATH"]
json_in = r'''{
"from": 0, "size": 100, "_source": ["path.real"],
"from": 0, "size": 50, "_source": ["path.real"],
"query": {
"query_string": {
"query": "(samba*) AND path.real.fulltext:\"%BASEPATH%\""
......
......@@ -125,7 +125,7 @@ class MdssvcTests(RpcInterfaceTestCase):
def test_mdscli_search(self):
exp_json_query = r'''{
"from": 0, "size": 100, "_source": ["path.real"],
"from": 0, "size": 50, "_source": ["path.real"],
"query": {
"query_string": {
"query": "(samba*) AND path.real.fulltext:\"%BASEPATH%\""
......@@ -157,7 +157,7 @@ class MdssvcTests(RpcInterfaceTestCase):
r'kMDItemFSName=="x\\x"'
)
exp_json_query = r'''{
"from": 0, "size": 100, "_source": ["path.real"],
"from": 0, "size": 50, "_source": ["path.real"],
"query": {
"query_string": {
"query": "(file.filename:x\\+x OR file.filename:x\\*x OR file.filename:x=x OR file.filename:x'x OR file.filename:x\\?x OR file.filename:x\\ x OR file.filename:x\\(x OR file.filename:x\\\"x OR file.filename:x\\\\x) AND path.real.fulltext:\"%BASEPATH%\""
......@@ -166,7 +166,7 @@ class MdssvcTests(RpcInterfaceTestCase):
}'''
fake_json_response = r'''{
"hits" : {
"total" : {"value" : 2},
"total" : {"value" : 9},
"hits" : [
{"_source" : {"path" : {"real" : "%BASEPATH%/x+x"}}},
{"_source" : {"path" : {"real" : "%BASEPATH%/x*x"}}},
......
......@@ -4,3 +4,5 @@ samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncIntegri
samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_get_tgt_chain\(promoted_dc\)
samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_get_tgt_and_anc\(promoted_dc\)
samba4.drs.getncchanges.python\(promoted_dc\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_get_tgt_multivalued_links\(promoted_dc\)
# Samba chooses to always increment the USN for the NC root at the point where it would otherwise show up.
samba4.drs.getncchanges.python\(.*\).getncchanges.DrsReplicaSyncIntegrityTestCase.test_repl_nc_is_first_nc_change_only\(
......@@ -3023,6 +3023,11 @@ sub provision($$)
msdfs root = yes
msdfs shuffle referrals = yes
guest ok = yes
[msdfs-share-wl]
path = $msdfs_shrdir
msdfs root = yes
wide links = yes
guest ok = yes
[msdfs-share2]
path = $msdfs_shrdir2
msdfs root = yes
......
......@@ -2850,11 +2850,15 @@ static void cli_start_connection_connected(struct tevent_req *subreq)
return;
}
subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
state->cli->timeout,
state->min_protocol,
state->max_protocol,
WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
subreq = smbXcli_negprot_send(
state,
state->ev,
state->cli->conn,
state->cli->timeout,
state->min_protocol,
state->max_protocol,
WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
NULL);
if (tevent_req_nomem(subreq, req)) {
return;
}
......@@ -2869,7 +2873,7 @@ static void cli_start_connection_done(struct tevent_req *subreq)
req, struct cli_start_connection_state);
NTSTATUS status;
status = smbXcli_negprot_recv(subreq);
status = smbXcli_negprot_recv(subreq, NULL, NULL);
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
......
......@@ -468,35 +468,43 @@ static int aio_pthread_openat_fn(vfs_handle_struct *handle,
return -1;
}
if (fsp->conn->sconn->client->server_multi_channel_enabled) {
if (fsp->conn->sconn->pool == NULL) {
/*
* a threadpool is required for async support
*/
aio_allow_open = false;
}
if (fsp->conn->sconn->client != NULL &&
fsp->conn->sconn->client->server_multi_channel_enabled) {
/*
* This module is not compatible with multi channel yet.
*/
aio_allow_open = false;
}
if (!aio_allow_open) {
/* aio opens turned off. */
return openat(fsp_get_pathref_fd(dirfsp),
smb_fname->base_name,
how->flags,
how->mode);
if (fsp->fsp_flags.is_pathref) {
/* Use SMB_VFS_NEXT_OPENAT() to call openat() with O_PATH. */
aio_allow_open = false;
}
if (!(how->flags & O_CREAT)) {
/* Only creates matter. */
return openat(fsp_get_pathref_fd(dirfsp),
smb_fname->base_name,
how->flags,
how->mode);
aio_allow_open = false;
}
if (!(how->flags & O_EXCL)) {
/* Only creates with O_EXCL matter. */
return openat(fsp_get_pathref_fd(dirfsp),
smb_fname->base_name,
how->flags,
how->mode);
aio_allow_open = false;
}
if (!aio_allow_open) {
/* aio opens turned off. */
return SMB_VFS_NEXT_OPENAT(handle,
dirfsp,
smb_fname,
fsp,
how);
}
/*
......
......@@ -106,6 +106,7 @@
struct widelinks_config {
bool active;
bool is_dfs_share;
char *cwd;
};
......@@ -134,7 +135,8 @@ static int widelinks_connect(struct vfs_handle_struct *handle,
DBG_ERR("vfs_widelinks module loaded with "
"widelinks = no\n");
}
config->is_dfs_share =
(lp_host_msdfs() && lp_msdfs_root(SNUM(handle->conn)));
SMB_VFS_HANDLE_SET_DATA(handle,
config,
NULL, /* free_fn */
......@@ -346,7 +348,7 @@ static int widelinks_openat(vfs_handle_struct *handle,
{
struct vfs_open_how how = *_how;
struct widelinks_config *config = NULL;
int ret;
SMB_VFS_HANDLE_GET_DATA(handle,
config,
struct widelinks_config,
......@@ -363,11 +365,33 @@ static int widelinks_openat(vfs_handle_struct *handle,
how.flags = (how.flags & ~O_NOFOLLOW);
}
return SMB_VFS_NEXT_OPENAT(handle,
ret = SMB_VFS_NEXT_OPENAT(handle,
dirfsp,
smb_fname,
fsp,
&how);
if (config->is_dfs_share && ret == -1 && errno == ENOENT) {
struct smb_filename *full_fname = NULL;
int lstat_ret;
full_fname = full_path_from_dirfsp_atname(talloc_tos(),
dirfsp,
smb_fname);
if (full_fname == NULL) {
errno = ENOMEM;
return -1;
}
lstat_ret = SMB_VFS_NEXT_LSTAT(handle,
full_fname);
if (lstat_ret != -1 &&
VALID_STAT(full_fname->st) &&
S_ISLNK(full_fname->st.st_ex_mode)) {
fsp->fsp_name->st = full_fname->st;
}
TALLOC_FREE(full_fname);
errno = ENOENT;
}
return ret;
}
static struct dirent *widelinks_readdir(vfs_handle_struct *handle,
......
......@@ -3305,9 +3305,13 @@ static NTSTATUS pdb_samba_dsdb_set_trusted_domain(struct pdb_methods *methods,
goto out;
}
msg->dn = ldb_dn_copy(tmp_ctx, base_dn);
msg->dn = samdb_system_container_dn(state->ldb, tmp_ctx);
if (msg->dn == NULL) {
status = NT_STATUS_NO_MEMORY;
goto out;
}
ok = ldb_dn_add_child_fmt(msg->dn, "cn=%s,cn=System", td->domain_name);
ok = ldb_dn_add_child_fmt(msg->dn, "cn=%s", td->domain_name);
if (!ok) {
status = NT_STATUS_NO_MEMORY;
goto out;
......@@ -3532,13 +3536,13 @@ static NTSTATUS pdb_samba_dsdb_del_trusted_domain(struct pdb_methods *methods,
return NT_STATUS_OK;
}
tdo_dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->ldb));
tdo_dn = samdb_system_container_dn(state->ldb, tmp_ctx);
if (tdo_dn == NULL) {
status = NT_STATUS_NO_MEMORY;
goto out;
}
ok = ldb_dn_add_child_fmt(tdo_dn, "cn=%s,cn=System", domain);
ok = ldb_dn_add_child_fmt(tdo_dn, "cn=%s", domain);
if (!ok) {
TALLOC_FREE(tmp_ctx);
status = NT_STATUS_NO_MEMORY;
......
......@@ -43,8 +43,8 @@
* RPC data marshalling and unmarshalling
******************************************************************************/
/* Spotlight epoch is UNIX epoch minus SPOTLIGHT_TIME_DELTA */
#define SPOTLIGHT_TIME_DELTA 280878921600ULL
/* Spotlight epoch is 1.1.2001 00:00 UTC */
#define SPOTLIGHT_TIME_DELTA 978307200 /* Diff from UNIX epoch to Spotlight epoch */
#define SQ_TYPE_NULL 0x0000
#define SQ_TYPE_COMPLEX 0x0200
......@@ -253,6 +253,10 @@ static ssize_t sl_pack_date(sl_time_t t, char *buf, ssize_t offset, size_t bufsi
{
uint64_t data;
uint64_t tag;
union {
double d;
uint64_t w;
} ieee_fp_union;
tag = sl_pack_tag(SQ_TYPE_DATE, 2, 1);
offset = sl_push_uint64_val(buf, offset, bufsize, tag);
......@@ -260,7 +264,10 @@ static ssize_t sl_pack_date(sl_time_t t, char *buf, ssize_t offset, size_t bufsi
return -1;
}
data = (t.tv_sec + SPOTLIGHT_TIME_DELTA) << 24;
ieee_fp_union.d = (double)(t.tv_sec - SPOTLIGHT_TIME_DELTA);
ieee_fp_union.d += (double)t.tv_usec / 1000000;
data = ieee_fp_union.w;
offset = sl_push_uint64_val(buf, offset, bufsize, data);
if (offset == -1) {
return -1;
......@@ -723,6 +730,11 @@ static int sl_unpack_date(DALLOC_CTX *query,
int i, result;
struct sl_tag tag;
uint64_t query_data64;
union {
double d;
uint64_t w;
} ieee_fp_union;
double fraction;
sl_time_t t;
offset = sl_unpack_tag(buf, offset, bufsize, encoding, &tag);
......@@ -735,9 +747,14 @@ static int sl_unpack_date(DALLOC_CTX *query,
if (offset == -1) {
return -1;
}
query_data64 = query_data64 >> 24;
t.tv_sec = query_data64 - SPOTLIGHT_TIME_DELTA;
t.tv_usec = 0;
ieee_fp_union.w = query_data64;
fraction = ieee_fp_union.d - (uint64_t)ieee_fp_union.d;
t = (sl_time_t) {
.tv_sec = ieee_fp_union.d + SPOTLIGHT_TIME_DELTA,
.tv_usec = fraction * 1000000
};
result = dalloc_add_copy(query, &t, sl_time_t);
if (result != 0) {
return -1;
......
......@@ -188,8 +188,10 @@ static bool add_filemeta(struct mds_ctx *mds_ctx,
if (result != 0) {
return false;
}
} else if (strcmp(attribute, "kMDItemFSContentChangeDate") == 0) {
sl_time.tv_sec = sp->st_ex_mtime.tv_sec;
} else if (strcmp(attribute, "kMDItemFSContentChangeDate") == 0 ||
strcmp(attribute, "kMDItemContentModificationDate") == 0)
{
sl_time = convert_timespec_to_timeval(sp->st_ex_mtime);
result = dalloc_add_copy(meta, &sl_time, sl_time_t);
if (result != 0) {
return false;
......@@ -306,10 +308,21 @@ static bool create_result_handle(struct sl_query *slq)
static bool add_results(sl_array_t *array, struct sl_query *slq)
{
sl_filemeta_t *fm;
uint64_t status = 0;
uint64_t status;
int result;
bool ok;
/*
* Taken from network traces against a macOS SMB Spotlight server: if
* the search is not finished yet in the backend macOS returns 0x23,
* otherwise 0x0.
*/
if (slq->state >= SLQ_STATE_DONE) {
status = 0;
} else {
status = 0x23;
}
/* FileMeta */
fm = dalloc_zero(array, sl_filemeta_t);
if (fm == NULL) {
......@@ -1126,7 +1139,7 @@ static bool slrpc_fetch_query_results(struct mds_ctx *mds_ctx,
goto error;
}
if (slq->state == SLQ_STATE_FULL) {
slq->state = SLQ_STATE_RESULTS;
slq->state = SLQ_STATE_RUNNING;
slq->mds_ctx->backend->search_cont(slq);
}
break;
......