mirror of
https://github.com/samba-team/samba.git
synced 2025-03-11 16:58:40 +03:00
Compare commits
35 Commits
24e89430b1
...
cc3a119585
Author | SHA1 | Date | |
---|---|---|---|
|
cc3a119585 | ||
|
81f92c8a62 | ||
|
6bcccb5c7b | ||
|
3572ffa6c5 | ||
|
2c7f99a68c | ||
|
dca5bd464d | ||
|
d618552669 | ||
|
1a74def369 | ||
|
bef660cfee | ||
|
70889a5f2f | ||
|
a7742b3519 | ||
|
fd7bfa6ad2 | ||
|
b6dd675372 | ||
|
6309b9a770 | ||
|
8c33f14b97 | ||
|
1dbcb533af | ||
|
432f8a3b69 | ||
|
5efc2a0ea9 | ||
|
a6dec953e7 | ||
|
7185f30946 | ||
|
d896ce18e0 | ||
|
fd6e9855c3 | ||
|
71aad11c2c | ||
|
7bd44b9fb0 | ||
|
8d902a2003 | ||
|
f2705e5b3b | ||
|
d921255c84 | ||
|
5e2aa6bf03 | ||
|
0c7983db19 | ||
|
8ee66862db | ||
|
74b127d037 | ||
|
d095ad71cc | ||
|
c063734ac3 | ||
|
b647d52691 | ||
|
2d2d5f675d |
@ -1775,6 +1775,7 @@ static NTSTATUS gensec_spnego_update_in(struct gensec_security *gensec_security,
|
||||
const DATA_BLOB in, TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *full_in)
|
||||
{
|
||||
DATA_BLOB consume = data_blob_null;
|
||||
struct spnego_state *spnego_state =
|
||||
talloc_get_type_abort(gensec_security->private_data,
|
||||
struct spnego_state);
|
||||
@ -1841,17 +1842,26 @@ static NTSTATUS gensec_spnego_update_in(struct gensec_security *gensec_security,
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
consume = in;
|
||||
expected = spnego_state->in_needed - spnego_state->in_frag.length;
|
||||
if (in.length > expected) {
|
||||
if (consume.length > expected) {
|
||||
if (spnego_state->state_position != SPNEGO_SERVER_START) {
|
||||
/*
|
||||
* we got more than expected
|
||||
*/
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/*
|
||||
* we got more than expected
|
||||
* In SPNEGO_SERVER_START we need to ignore unexpected
|
||||
* bytes at the end.
|
||||
*/
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
consume.length = expected;
|
||||
}
|
||||
|
||||
if (in.length == spnego_state->in_needed) {
|
||||
if (consume.length == spnego_state->in_needed) {
|
||||
/*
|
||||
* if the in.length contains the full blob
|
||||
* if the consume.length contains the full blob
|
||||
* we are done.
|
||||
*
|
||||
* Note: this implies spnego_state->in_frag.length == 0,
|
||||
@ -1859,13 +1869,13 @@ static NTSTATUS gensec_spnego_update_in(struct gensec_security *gensec_security,
|
||||
* because we already know that we did not get
|
||||
* more than expected.
|
||||
*/
|
||||
*full_in = in;
|
||||
*full_in = consume;
|
||||
spnego_state->in_needed = 0;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
ok = data_blob_append(spnego_state, &spnego_state->in_frag,
|
||||
in.data, in.length);
|
||||
consume.data, consume.length);
|
||||
if (!ok) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ struct auth_session_info;
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_AUTH
|
||||
|
||||
#define NTLMSSP_MAX_UPDATE_SIZE 2888
|
||||
|
||||
/**
|
||||
* Callbacks for NTLMSSP - for both client and server operating modes
|
||||
*
|
||||
@ -136,6 +138,13 @@ static NTSTATUS gensec_ntlmssp_update_find(struct gensec_security *gensec_securi
|
||||
}
|
||||
}
|
||||
|
||||
if (input.length > NTLMSSP_MAX_UPDATE_SIZE) {
|
||||
DBG_WARNING("reject large command=%u message, length %zu > %u)\n",
|
||||
ntlmssp_command, input.length,
|
||||
NTLMSSP_MAX_UPDATE_SIZE);
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (ntlmssp_command != gensec_ntlmssp->ntlmssp_state->expected_state) {
|
||||
DEBUG(2, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command,
|
||||
gensec_ntlmssp->ntlmssp_state->expected_state));
|
||||
|
@ -142,12 +142,6 @@ NTSTATUS gensec_ntlmssp_resume_ccache(struct gensec_security *gensec_security,
|
||||
|
||||
/* parse the NTLMSSP packet */
|
||||
|
||||
if (in.length > UINT16_MAX) {
|
||||
DEBUG(1, ("%s: reject large request of length %u\n",
|
||||
__func__, (unsigned int)in.length));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ok = msrpc_parse(ntlmssp_state, &in, "Cdd",
|
||||
"NTLMSSP",
|
||||
&ntlmssp_command,
|
||||
|
@ -124,12 +124,6 @@ NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security
|
||||
#endif
|
||||
|
||||
if (request.length) {
|
||||
if (request.length > UINT16_MAX) {
|
||||
DEBUG(1, ("ntlmssp_server_negotiate: reject large request of length %u\n",
|
||||
(unsigned int)request.length));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd",
|
||||
"NTLMSSP",
|
||||
&ntlmssp_command,
|
||||
|
@ -98,7 +98,6 @@ bld.SAMBA_PIDL_LIST('PIDL',
|
||||
ODJ.idl
|
||||
printcap.idl
|
||||
rap.idl
|
||||
schannel.idl
|
||||
smb2_lease_struct.idl
|
||||
''',
|
||||
options='--header --ndr-parser',
|
||||
@ -135,6 +134,7 @@ bld.SAMBA_PIDL_LIST('PIDL',
|
||||
idmap.idl
|
||||
krb5pac.idl
|
||||
krb5ccache.idl
|
||||
schannel.idl
|
||||
messaging.idl
|
||||
misc.idl
|
||||
nbt.idl
|
||||
|
@ -239,8 +239,10 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
|
||||
enum ndr_err_code ndr_err;
|
||||
uint16_t data_and_pad;
|
||||
uint16_t auth_length;
|
||||
uint16_t auth_offset;
|
||||
uint32_t tmp_length;
|
||||
uint32_t max_pad_len = 0;
|
||||
DATA_BLOB auth_blob;
|
||||
|
||||
ZERO_STRUCTP(auth);
|
||||
if (_auth_length != NULL) {
|
||||
@ -276,12 +278,21 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
|
||||
|
||||
auth_length = DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length;
|
||||
if (pkt_trailer->length < auth_length) {
|
||||
return NT_STATUS_RPC_PROTOCOL_ERROR;
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
data_and_pad = pkt_trailer->length - auth_length;
|
||||
auth_offset = pkt->frag_length - auth_length;
|
||||
if ((auth_offset % 4) != 0) {
|
||||
DBG_WARNING("auth_offset[%u] not 4 byte aligned\n",
|
||||
(unsigned)auth_offset);
|
||||
auth->auth_context_id = DCERPC_BIND_NAK_REASON_NOT_SPECIFIED;
|
||||
return NT_STATUS_RPC_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
ndr = ndr_pull_init_blob(pkt_trailer, mem_ctx);
|
||||
auth_blob = data_blob_const(pkt_trailer->data + data_and_pad,
|
||||
auth_length);
|
||||
ndr = ndr_pull_init_blob(&auth_blob, mem_ctx);
|
||||
if (!ndr) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
@ -290,12 +301,6 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
|
||||
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_advance(ndr, data_and_pad);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
talloc_free(ndr);
|
||||
return ndr_map_error2ntstatus(ndr_err);
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
talloc_free(ndr);
|
||||
@ -323,11 +328,20 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
|
||||
* protection for REQUEST and RESPONSE pdus, where the
|
||||
* auth_pad_length field is actually used by the caller.
|
||||
*/
|
||||
tmp_length = DCERPC_REQUEST_LENGTH;
|
||||
tmp_length += DCERPC_AUTH_TRAILER_LENGTH;
|
||||
tmp_length += pkt->auth_length;
|
||||
if (tmp_length < pkt->frag_length) {
|
||||
max_pad_len = pkt->frag_length - tmp_length;
|
||||
switch (pkt->ptype) {
|
||||
case DCERPC_PKT_BIND:
|
||||
case DCERPC_PKT_ALTER:
|
||||
case DCERPC_PKT_AUTH3:
|
||||
max_pad_len = 0;
|
||||
break;
|
||||
default:
|
||||
tmp_length = DCERPC_REQUEST_LENGTH;
|
||||
tmp_length += DCERPC_AUTH_TRAILER_LENGTH;
|
||||
tmp_length += pkt->auth_length;
|
||||
if (tmp_length < pkt->frag_length) {
|
||||
max_pad_len = pkt->frag_length - tmp_length;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (max_pad_len < auth->auth_pad_length) {
|
||||
DEBUG(1, (__location__ ": ERROR: pad length too large. "
|
||||
@ -336,6 +350,7 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
|
||||
auth->auth_pad_length));
|
||||
talloc_free(ndr);
|
||||
ZERO_STRUCTP(auth);
|
||||
auth->auth_context_id = DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED;
|
||||
return NT_STATUS_RPC_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
@ -346,10 +361,9 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
|
||||
*
|
||||
* See also bug #11982.
|
||||
*/
|
||||
if (auth_data_only && data_and_pad == 0 &&
|
||||
auth->auth_pad_length > 0) {
|
||||
if (auth_data_only) {
|
||||
/*
|
||||
* we need to ignore invalid auth_pad_length
|
||||
* We need to ignore auth_pad_length
|
||||
* values for BIND_*, ALTER_* and AUTH3 pdus.
|
||||
*/
|
||||
auth->auth_pad_length = 0;
|
||||
@ -365,34 +379,7 @@ NTSTATUS dcerpc_pull_auth_trailer(const struct ncacn_packet *pkt,
|
||||
auth->auth_pad_length);
|
||||
talloc_free(ndr);
|
||||
ZERO_STRUCTP(auth);
|
||||
return NT_STATUS_RPC_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
if (auth_data_only && data_and_pad > auth->auth_pad_length) {
|
||||
DBG_WARNING(__location__ ": ERROR: auth_data_only pad length mismatch. "
|
||||
"Client sent a longer BIND packet than expected by %"PRIu16" bytes "
|
||||
"(pkt_trailer->length=%zu - auth_length=%"PRIu16") "
|
||||
"= %"PRIu16" auth_pad_length=%"PRIu8"\n",
|
||||
data_and_pad - auth->auth_pad_length,
|
||||
pkt_trailer->length,
|
||||
auth_length,
|
||||
data_and_pad,
|
||||
auth->auth_pad_length);
|
||||
talloc_free(ndr);
|
||||
ZERO_STRUCTP(auth);
|
||||
return NT_STATUS_RPC_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
if (auth_data_only && data_and_pad != auth->auth_pad_length) {
|
||||
DBG_WARNING(__location__ ": ERROR: auth_data_only pad length mismatch. "
|
||||
"Calculated %"PRIu16" (pkt_trailer->length=%zu - auth_length=%"PRIu16") "
|
||||
"but auth_pad_length=%"PRIu8"\n",
|
||||
data_and_pad,
|
||||
pkt_trailer->length,
|
||||
auth_length,
|
||||
auth->auth_pad_length);
|
||||
talloc_free(ndr);
|
||||
ZERO_STRUCTP(auth);
|
||||
auth->auth_context_id = DCERPC_BIND_NAK_REASON_NOT_SPECIFIED;
|
||||
return NT_STATUS_RPC_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,12 @@ static bool dcesrv_auth_prepare_gensec(struct dcesrv_call_state *call)
|
||||
auth->auth_level = call->in_auth_info.auth_level;
|
||||
auth->auth_context_id = call->in_auth_info.auth_context_id;
|
||||
|
||||
if (auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT &&
|
||||
!call->conn->got_explicit_auth_level_connect)
|
||||
{
|
||||
call->conn->default_auth_level_connect = auth;
|
||||
}
|
||||
|
||||
cb->auth.become_root();
|
||||
status = cb->auth.gensec_prepare(
|
||||
auth,
|
||||
@ -320,8 +326,13 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call)
|
||||
*/
|
||||
auth->auth_type = DCERPC_AUTH_TYPE_NONE;
|
||||
auth->auth_level = DCERPC_AUTH_LEVEL_NONE;
|
||||
auth->auth_context_id =
|
||||
DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED;
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
|
||||
auth->auth_context_id =
|
||||
call->in_auth_info.auth_context_id;
|
||||
} else {
|
||||
auth->auth_context_id =
|
||||
DCERPC_BIND_NAK_REASON_NOT_SPECIFIED;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -374,12 +385,6 @@ NTSTATUS dcesrv_auth_complete(struct dcesrv_call_state *call, NTSTATUS status)
|
||||
}
|
||||
auth->auth_finished = true;
|
||||
|
||||
if (auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT &&
|
||||
!call->conn->got_explicit_auth_level_connect)
|
||||
{
|
||||
call->conn->default_auth_level_connect = auth;
|
||||
}
|
||||
|
||||
if (call->pkt.ptype != DCERPC_PKT_AUTH3) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@ -440,11 +445,38 @@ bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call)
|
||||
struct dcesrv_auth *auth = call->auth_state;
|
||||
NTSTATUS status;
|
||||
|
||||
if (pkt->auth_length == 0) {
|
||||
if (pkt->frag_length > call->conn->transport_max_recv_frag) {
|
||||
/*
|
||||
* Note that we don't check against the negotiated
|
||||
* max_recv_frag, but a hard coded value from
|
||||
* the transport.
|
||||
*/
|
||||
call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pkt->auth_length > 4096) {
|
||||
call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auth->auth_finished) {
|
||||
call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!auth->auth_started) {
|
||||
call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auth->auth_invalid) {
|
||||
call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pkt->auth_length == 0) {
|
||||
call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -460,23 +492,36 @@ bool dcesrv_auth_prepare_auth3(struct dcesrv_call_state *call)
|
||||
status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info,
|
||||
&call->in_auth_info, NULL, true);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
struct dcerpc_auth *auth_info = &call->in_auth_info;
|
||||
uint32_t nr = auth_info->auth_context_id;
|
||||
|
||||
/*
|
||||
* Windows returns DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY
|
||||
* instead of DCERPC_NCA_S_PROTO_ERROR.
|
||||
* instead of DCERPC_NCA_S_PROTO_ERROR in most cases.
|
||||
*/
|
||||
call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR) &&
|
||||
nr != DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED)
|
||||
{
|
||||
call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (call->in_auth_info.auth_type != auth->auth_type) {
|
||||
call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (call->in_auth_info.auth_level != auth->auth_level) {
|
||||
call->fault_code = DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (call->in_auth_info.auth_context_id != auth->auth_context_id) {
|
||||
call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -615,12 +660,12 @@ bool dcesrv_auth_pkt_pull(struct dcesrv_call_state *call,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!auth->auth_finished) {
|
||||
call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
|
||||
if (auth->auth_invalid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auth->auth_invalid) {
|
||||
if (!auth->auth_finished) {
|
||||
call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "system/network.h"
|
||||
#include "lib/util/idtree_random.h"
|
||||
#include "nsswitch/winbind_client.h"
|
||||
#include "libcli/smb/tstream_smbXcli_np.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
@ -676,6 +677,8 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
|
||||
{
|
||||
struct dcesrv_auth *auth = NULL;
|
||||
struct dcesrv_connection *p = NULL;
|
||||
enum dcerpc_transport_t transport =
|
||||
dcerpc_binding_get_transport(ep->ep_description);
|
||||
|
||||
if (!session_info) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
@ -695,9 +698,21 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
|
||||
p->event_ctx = event_ctx;
|
||||
p->state_flags = state_flags;
|
||||
p->allow_bind = true;
|
||||
p->max_recv_frag = 5840;
|
||||
p->max_xmit_frag = 5840;
|
||||
p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
|
||||
/*
|
||||
* SMB uses 4280, while all others use 5480
|
||||
* note that p->transport_max_recv_frag is fixed
|
||||
* for the lifetime of the connection, it's not
|
||||
* negotiated by bind.
|
||||
*/
|
||||
if (transport == NCACN_NP) {
|
||||
p->transport_max_recv_frag = TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE;
|
||||
} else {
|
||||
p->transport_max_recv_frag = DCERPC_FRAG_MAX_SIZE;
|
||||
}
|
||||
/* these might be overwritten by BIND */
|
||||
p->max_recv_frag = p->transport_max_recv_frag;
|
||||
p->max_xmit_frag = p->transport_max_recv_frag;
|
||||
|
||||
p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx,
|
||||
NULL,
|
||||
@ -1116,12 +1131,20 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
|
||||
DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that BIND and ALTER allow frag_len up to UINT16_MAX,
|
||||
* so we don't check again frag_len against
|
||||
* call->conn->transport_max_recv_frag
|
||||
*/
|
||||
|
||||
/* max_recv_frag and max_xmit_frag result always in the same value! */
|
||||
max_req = MIN(call->pkt.u.bind.max_xmit_frag,
|
||||
call->pkt.u.bind.max_recv_frag);
|
||||
/*
|
||||
* The values are between 2048 and 5840 tested against Windows 2012R2
|
||||
* via ncacn_ip_tcp on port 135.
|
||||
*
|
||||
* call->conn->transport_max_recv_frag stays fixed at 5840 (4280 for SMB)
|
||||
*/
|
||||
max_req = MAX(2048, max_req);
|
||||
max_rep = MIN(max_req, conn->max_recv_frag);
|
||||
@ -1135,13 +1158,23 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
|
||||
status = dce_ctx->callbacks->assoc_group.find(
|
||||
call, dce_ctx->callbacks->assoc_group.private_data);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DBG_NOTICE("Failed to find assoc_group 0x%08x: %s\n",
|
||||
call->pkt.u.bind.assoc_group_id, nt_errstr(status));
|
||||
char *raddr = NULL;
|
||||
|
||||
raddr = tsocket_address_string(call->conn->remote_address, call);
|
||||
|
||||
endpoint = dcerpc_binding_get_string_option(
|
||||
call->conn->endpoint->ep_description,
|
||||
"endpoint");
|
||||
|
||||
DBG_WARNING("Failed to find assoc_group 0x%08x on ep[%s] raddr[%s]: %s\n",
|
||||
call->pkt.u.bind.assoc_group_id,
|
||||
endpoint, raddr, nt_errstr(status));
|
||||
return dcesrv_bind_nak(call, 0);
|
||||
}
|
||||
|
||||
if (call->pkt.u.bind.num_contexts < 1) {
|
||||
return dcesrv_bind_nak(call, 0);
|
||||
return dcesrv_bind_nak(call,
|
||||
DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
|
||||
@ -1329,7 +1362,7 @@ static void dcesrv_bind_done(struct tevent_req *subreq)
|
||||
|
||||
status = dcesrv_auth_complete(call, status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
status = dcesrv_bind_nak(call, 0);
|
||||
status = dcesrv_bind_nak(call, DCERPC_BIND_NAK_REASON_INVALID_CHECKSUM);
|
||||
dcesrv_conn_auth_wait_finished(conn, status);
|
||||
return;
|
||||
}
|
||||
@ -1386,14 +1419,6 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
|
||||
struct tevent_req *subreq = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!auth->auth_started) {
|
||||
return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
|
||||
}
|
||||
|
||||
if (auth->auth_finished) {
|
||||
return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
|
||||
}
|
||||
|
||||
status = dcerpc_verify_ncacn_packet_header(&call->pkt,
|
||||
DCERPC_PKT_AUTH3,
|
||||
call->pkt.u.auth3.auth_info.length,
|
||||
@ -1749,6 +1774,12 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
|
||||
return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that BIND and ALTER allow frag_len up to UINT16_MAX,
|
||||
* so we don't check again frag_len against
|
||||
* call->conn->transport_max_recv_frag
|
||||
*/
|
||||
|
||||
auth_ok = dcesrv_auth_alter(call);
|
||||
if (!auth_ok) {
|
||||
if (call->fault_code != 0) {
|
||||
@ -1866,7 +1897,20 @@ static void dcesrv_alter_done(struct tevent_req *subreq)
|
||||
|
||||
status = dcesrv_auth_complete(call, status);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
|
||||
/*
|
||||
* NT_STATUS_ACCESS_DENIED from gensec means
|
||||
* a signing check or decryption failure,
|
||||
* which should result in DCERPC_FAULT_SEC_PKG_ERROR.
|
||||
*
|
||||
* Any other status, e.g. NT_STATUS_LOGON_FAILURE or
|
||||
* NT_STATUS_INVALID_PARAMETER should result in
|
||||
* DCERPC_FAULT_ACCESS_DENIED.
|
||||
*/
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
|
||||
status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
|
||||
} else {
|
||||
status = dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
|
||||
}
|
||||
dcesrv_conn_auth_wait_finished(conn, status);
|
||||
return;
|
||||
}
|
||||
@ -2006,6 +2050,16 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
|
||||
auth->auth_level,
|
||||
derpc_transport_string_by_transport(transport),
|
||||
addr));
|
||||
if (!call->conn->got_explicit_auth_level_non_connect) {
|
||||
/*
|
||||
* If there was is no auth context with
|
||||
* a level higher than DCERPC_AUTH_LEVEL_CONNECT,
|
||||
* the connection should be disconnected
|
||||
* after sending the fault.
|
||||
*/
|
||||
return dcesrv_fault_disconnect0(call,
|
||||
DCERPC_FAULT_ACCESS_DENIED);
|
||||
}
|
||||
return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
|
||||
}
|
||||
break;
|
||||
@ -2026,6 +2080,16 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
|
||||
auth->auth_level,
|
||||
derpc_transport_string_by_transport(transport),
|
||||
addr));
|
||||
if (!call->conn->got_explicit_auth_level_non_connect) {
|
||||
/*
|
||||
* If there was is no auth context with
|
||||
* a level higher than DCERPC_AUTH_LEVEL_CONNECT,
|
||||
* the connection should be disconnected
|
||||
* after sending the fault.
|
||||
*/
|
||||
return dcesrv_fault_disconnect0(call,
|
||||
DCERPC_FAULT_ACCESS_DENIED);
|
||||
}
|
||||
return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
@ -2197,6 +2261,8 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
|
||||
dce_conn->default_auth_level_connect = NULL;
|
||||
if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
|
||||
dce_conn->got_explicit_auth_level_connect = true;
|
||||
} else if (auth_level >= DCERPC_AUTH_LEVEL_PACKET) {
|
||||
dce_conn->got_explicit_auth_level_non_connect = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2264,7 +2330,13 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
|
||||
dcesrv_default_auth_state_prepare_request(call);
|
||||
|
||||
if (call->auth_state->auth_started &&
|
||||
!call->auth_state->auth_invalid &&
|
||||
!call->auth_state->auth_finished) {
|
||||
/*
|
||||
* We have this check here instead of
|
||||
* relying on the check in dcesrv_auth_pkt_pull()
|
||||
* because the fault should have context_id=0
|
||||
*/
|
||||
return dcesrv_fault_disconnect(call,
|
||||
DCERPC_NCA_S_PROTO_ERROR);
|
||||
}
|
||||
@ -2286,14 +2358,15 @@ static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
|
||||
DCERPC_NCA_S_PROTO_ERROR);
|
||||
}
|
||||
|
||||
if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
|
||||
if (call->pkt.frag_length > call->conn->transport_max_recv_frag) {
|
||||
/*
|
||||
* We don't use dcesrv_fault_disconnect()
|
||||
* here, because we don't want to set
|
||||
* DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
||||
*
|
||||
* Note that we don't check against the negotiated
|
||||
* max_recv_frag, but a hard coded value.
|
||||
* max_recv_frag, but a hard coded value from
|
||||
* the transport.
|
||||
*/
|
||||
return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
|
||||
}
|
||||
|
@ -272,6 +272,7 @@ struct dcesrv_connection {
|
||||
struct dcesrv_call_state *call_list;
|
||||
|
||||
/* the maximum size the client wants to receive */
|
||||
uint16_t transport_max_recv_frag;
|
||||
uint16_t max_recv_frag;
|
||||
uint16_t max_xmit_frag;
|
||||
|
||||
@ -305,6 +306,7 @@ struct dcesrv_connection {
|
||||
struct dcesrv_auth *default_auth_state;
|
||||
size_t max_auth_states;
|
||||
struct dcesrv_auth *auth_states;
|
||||
bool got_explicit_auth_level_non_connect;
|
||||
bool got_explicit_auth_level_connect;
|
||||
struct dcesrv_auth *default_auth_level_connect;
|
||||
bool client_hdr_signing;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -56,7 +56,17 @@ class smb_pipe_socket(object):
|
||||
return
|
||||
|
||||
def close(self):
|
||||
self.smbconn.close(self.smbfid)
|
||||
try:
|
||||
self.smbconn.close(self.smbfid)
|
||||
except NTSTATUSError as e:
|
||||
if e.args[0] == NT_STATUS_CONNECTION_DISCONNECTED:
|
||||
pass
|
||||
elif e.args[0] == NT_STATUS_PIPE_DISCONNECTED:
|
||||
pass
|
||||
elif e.args[0] == NT_STATUS_IO_TIMEOUT:
|
||||
pass
|
||||
else:
|
||||
raise e
|
||||
del self.smbconn
|
||||
|
||||
def settimeout(self, timeo):
|
||||
@ -152,6 +162,12 @@ class RawDCERPCTest(TestCase):
|
||||
|
||||
self.ignore_random_pad = samba.tests.env_get_var_value('IGNORE_RANDOM_PAD',
|
||||
allow_missing=True)
|
||||
self.auth_level_connect_lsa = samba.tests.env_get_var_value('AUTH_LEVEL_CONNECT_LSA',
|
||||
allow_missing=True)
|
||||
self.allow_bind_auth_pad = samba.tests.env_get_var_value('ALLOW_BIND_AUTH_PAD',
|
||||
allow_missing=True)
|
||||
self.legacy_bind_nak_no_reason = samba.tests.env_get_var_value('LEGACY_BIND_NACK_NO_REASON',
|
||||
allow_missing=True)
|
||||
self.host = samba.tests.env_get_var_value('SERVER')
|
||||
self.target_hostname = samba.tests.env_get_var_value('TARGET_HOSTNAME', allow_missing=True)
|
||||
if self.target_hostname is None:
|
||||
@ -661,34 +677,45 @@ class RawDCERPCTest(TestCase):
|
||||
self.secondary_address = None
|
||||
self.connect()
|
||||
|
||||
def send_pdu(self, req, ndr_print=None, hexdump=None):
|
||||
def prepare_pdu(self, req, ndr_print=None, hexdump=None):
|
||||
if ndr_print is None:
|
||||
ndr_print = self.do_ndr_print
|
||||
if hexdump is None:
|
||||
hexdump = self.do_hexdump
|
||||
req_pdu = ndr_pack(req)
|
||||
if ndr_print:
|
||||
sys.stderr.write("prepare_pdu: %s" % samba.ndr.ndr_print(req))
|
||||
if hexdump:
|
||||
sys.stderr.write("prepare_pdu: %d\n%s" % (len(req_pdu), self.hexdump(req_pdu)))
|
||||
return req_pdu
|
||||
|
||||
def send_pdu_blob(self, req_pdu, hexdump=None):
|
||||
if hexdump is None:
|
||||
hexdump = self.do_hexdump
|
||||
try:
|
||||
req_pdu = ndr_pack(req)
|
||||
if ndr_print:
|
||||
sys.stderr.write("send_pdu: %s" % samba.ndr.ndr_print(req))
|
||||
if hexdump:
|
||||
sys.stderr.write("send_pdu: %d\n%s" % (len(req_pdu), self.hexdump(req_pdu)))
|
||||
sys.stderr.write("send_pdu_blob: %d\n%s" % (len(req_pdu), self.hexdump(req_pdu)))
|
||||
while True:
|
||||
sent = self.s.send(req_pdu, 0)
|
||||
if sent == len(req_pdu):
|
||||
break
|
||||
req_pdu = req_pdu[sent:]
|
||||
except socket.error as e:
|
||||
self._disconnect("send_pdu: %s" % e)
|
||||
self._disconnect("send_pdu_blob: %s" % e)
|
||||
raise
|
||||
except IOError as e:
|
||||
self._disconnect("send_pdu: %s" % e)
|
||||
self._disconnect("send_pdu_blob: %s" % e)
|
||||
raise
|
||||
except NTSTATUSError as e:
|
||||
self._disconnect("send_pdu: %s" % e)
|
||||
self._disconnect("send_pdu_blob: %s" % e)
|
||||
raise
|
||||
finally:
|
||||
pass
|
||||
|
||||
def send_pdu(self, req, ndr_print=None, hexdump=None):
|
||||
req_pdu = self.prepare_pdu(req, ndr_print=ndr_print, hexdump=False)
|
||||
return self.send_pdu_blob(req_pdu, hexdump=hexdump)
|
||||
|
||||
def recv_raw(self, hexdump=None, timeout=None):
|
||||
rep_pdu = None
|
||||
if hexdump is None:
|
||||
@ -862,6 +889,7 @@ class RawDCERPCTest(TestCase):
|
||||
if len(ai) > samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH:
|
||||
p.auth_length = len(ai) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH
|
||||
else:
|
||||
self.assertEqual(len(ai), 0)
|
||||
p.auth_length = 0
|
||||
p.call_id = call_id
|
||||
p.u = payload
|
||||
@ -974,10 +1002,10 @@ class RawDCERPCTest(TestCase):
|
||||
if len(ai) > samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH:
|
||||
self.assertEqual(p.auth_length,
|
||||
len(ai) - samba.dcerpc.dcerpc.DCERPC_AUTH_TRAILER_LENGTH)
|
||||
elif auth_length is not None:
|
||||
self.assertEqual(p.auth_length, auth_length)
|
||||
else:
|
||||
elif auth_length is None:
|
||||
self.assertEqual(p.auth_length, 0)
|
||||
if auth_length is not None:
|
||||
self.assertEqual(p.auth_length, auth_length)
|
||||
self.assertEqual(p.call_id, call_id)
|
||||
|
||||
return
|
||||
|
@ -19,3 +19,7 @@
|
||||
^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_last_only_requests\(ad_member\)
|
||||
^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_mix_requests\(ad_member\)
|
||||
^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_none_only_requests\(ad_member\)
|
||||
^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_schannel_invalid_alter_no_padding\(ad_member\)
|
||||
^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_schannel_invalid_alter_tail_padding\(ad_member\)
|
||||
^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_schannel_invalid_auth3_no_padding\(ad_member\)
|
||||
^samba.tests.dcerpc.raw_protocol.*.TestDCERPC_BIND.test_schannel_invalid_auth3_tail_padding\(ad_member\)
|
||||
|
28
selftest/expectedfail.d/samba4.rpc.backupkey
Normal file
28
selftest/expectedfail.d/samba4.rpc.backupkey
Normal file
@ -0,0 +1,28 @@
|
||||
# We require seal and the test also runs differently against Windows 2022 with sign
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.restore_guid\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.restore_guid.version.3\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.restore_guid_2nd\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.unable_to_decrypt_secret\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.wrong_user_restore_guid\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.wrong_version_restore_guid\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.bad_magic_on_secret_restore_guid\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.bad_hash_on_secret_restore_guid\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.bad_magic_on_accesscheck_restore_guid\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.bad_cert_guid_restore_guid\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.empty_request_restore_guid\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.retreive_backup_key_guid_validate\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_encrypt_decrypt\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_decrypt_wrong_keyGUID\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_empty_request\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_decrypt_short_request\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_decrypt_wrong_magic\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_decrypt_wrong_r2\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_decrypt_wrong_payload_length\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_decrypt_short_payload_length\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_decrypt_zero_payload_length\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_decrypt_wrong_ciphertext_length\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_decrypt_short_ciphertext_length\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_decrypt_zero_ciphertext_length\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_encrypt_decrypt_remote_key\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_encrypt_decrypt_wrong_key\(ad_dc_default\)
|
||||
^samba4.rpc.backupkey.with.sign.backupkey.server_wrap_encrypt_decrypt_wrong_sid\(ad_dc_default\)
|
@ -2208,7 +2208,6 @@ sub provision_chgdcpass($$)
|
||||
|
||||
my $extra_smb_conf = "
|
||||
check password script = $self->{srcdir}/selftest/checkpassword_arg1.sh ${unacceptable_password}
|
||||
allow dcerpc auth level connect:lsarpc = yes
|
||||
dcesrv:max auth states = 8
|
||||
drs:broken_samba_4.5_get_anc_emulation = true
|
||||
drs:get_tgt_support = false
|
||||
|
@ -3376,6 +3376,7 @@ static NTSTATUS check_and_store_share_mode(
|
||||
struct share_mode_lock *lck,
|
||||
uint32_t create_disposition,
|
||||
uint32_t access_mask,
|
||||
uint32_t open_access_mask,
|
||||
uint32_t share_access,
|
||||
int oplock_request,
|
||||
const struct smb2_lease *lease,
|
||||
@ -3402,7 +3403,7 @@ static NTSTATUS check_and_store_share_mode(
|
||||
status = handle_share_mode_lease(fsp,
|
||||
lck,
|
||||
create_disposition,
|
||||
access_mask,
|
||||
open_access_mask,
|
||||
share_access,
|
||||
oplock_request,
|
||||
lease,
|
||||
@ -3732,6 +3733,7 @@ struct open_ntcreate_lock_state {
|
||||
struct smb_request *req;
|
||||
uint32_t create_disposition;
|
||||
uint32_t access_mask;
|
||||
uint32_t open_access_mask;
|
||||
uint32_t share_access;
|
||||
int oplock_request;
|
||||
const struct smb2_lease *lease;
|
||||
@ -3760,6 +3762,7 @@ static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
|
||||
lck,
|
||||
state->create_disposition,
|
||||
state->access_mask,
|
||||
state->open_access_mask,
|
||||
state->share_access,
|
||||
state->oplock_request,
|
||||
state->lease,
|
||||
@ -4394,6 +4397,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
.req = req,
|
||||
.create_disposition = create_disposition,
|
||||
.access_mask = access_mask,
|
||||
.open_access_mask = open_access_mask,
|
||||
.share_access = share_access,
|
||||
.oplock_request = oplock_request,
|
||||
.lease = lease,
|
||||
@ -5092,6 +5096,7 @@ static NTSTATUS open_directory(connection_struct *conn,
|
||||
.req = req,
|
||||
.create_disposition = create_disposition,
|
||||
.access_mask = access_mask,
|
||||
.open_access_mask = access_mask,
|
||||
.share_access = share_access,
|
||||
.oplock_request = NO_OPLOCK,
|
||||
.lease = NULL,
|
||||
|
@ -1790,6 +1790,8 @@ static bool fork_domain_child(struct winbindd_child *child)
|
||||
process_set_title("wb[%s]", "domain child [%s]", child_domain->name);
|
||||
} else if (is_idmap_child(child)) {
|
||||
process_set_title("wb-idmap", "idmap child");
|
||||
} else if (is_locator_child(child)) {
|
||||
process_set_title("wb-locator", "locator child");
|
||||
}
|
||||
|
||||
/* Handle online/offline messages. */
|
||||
|
@ -34,6 +34,15 @@ struct winbindd_child *locator_child(void)
|
||||
return static_locator_child;
|
||||
}
|
||||
|
||||
bool is_locator_child(const struct winbindd_child *child)
|
||||
{
|
||||
if (child == static_locator_child) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct dcerpc_binding_handle *locator_child_handle(void)
|
||||
{
|
||||
return static_locator_child->binding_handle;
|
||||
|
@ -407,6 +407,7 @@ bool lp_scan_idmap_domains(bool (*fn)(const char *domname,
|
||||
|
||||
NTSTATUS init_locator_child(TALLOC_CTX *mem_ctx);
|
||||
struct winbindd_child *locator_child(void);
|
||||
bool is_locator_child(const struct winbindd_child *child);
|
||||
struct dcerpc_binding_handle *locator_child_handle(void);
|
||||
|
||||
/* The following definitions come from winbindd/winbindd_misc.c */
|
||||
|
@ -282,6 +282,13 @@ bld.SAMBA_PYTHON('python_gmsa',
|
||||
cflags_end=gen_cflags
|
||||
)
|
||||
|
||||
bld.SAMBA_PYTHON('python_schannel',
|
||||
source='../../librpc/gen_ndr/py_schannel.c',
|
||||
deps='NDR_SCHANNEL %s %s' % (pytalloc_util, pyrpc_util),
|
||||
realname='samba/dcerpc/schannel.so',
|
||||
cflags_end=gen_cflags
|
||||
)
|
||||
|
||||
bld.SAMBA_PYTHON('python_netlogon',
|
||||
source='../../librpc/gen_ndr/py_netlogon.c',
|
||||
deps='RPC_NDR_NETLOGON %s %s' % (pytalloc_util, pyrpc_util),
|
||||
|
@ -1356,11 +1356,15 @@ planoldpythontestsuite(
|
||||
planoldpythontestsuite("ad_dc_ntvfs", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'])
|
||||
planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.dnsserver", extra_args=['-U"$USERNAME%$PASSWORD"'])
|
||||
|
||||
for env in ["chgdcpass", "ad_member"]:
|
||||
planoldpythontestsuite(env, "samba.tests.dcerpc.raw_protocol",
|
||||
environ={"MAX_NUM_AUTH": "8",
|
||||
"USERNAME": "$DC_USERNAME",
|
||||
"PASSWORD": "$DC_PASSWORD"})
|
||||
planoldpythontestsuite("chgdcpass", "samba.tests.dcerpc.raw_protocol",
|
||||
environ={"MAX_NUM_AUTH": "8",
|
||||
"USERNAME": "$DC_USERNAME",
|
||||
"PASSWORD": "$DC_PASSWORD"})
|
||||
planoldpythontestsuite("ad_member", "samba.tests.dcerpc.raw_protocol",
|
||||
environ={"MAX_NUM_AUTH": "8",
|
||||
"AUTH_LEVEL_CONNECT_LSA": "1",
|
||||
"USERNAME": "$DC_USERNAME",
|
||||
"PASSWORD": "$DC_PASSWORD"})
|
||||
|
||||
if have_heimdal_support:
|
||||
planoldpythontestsuite("ad_dc_smb1:local", "samba.tests.auth_log", extra_args=['-U"$USERNAME%$PASSWORD"'],
|
||||
|
@ -886,8 +886,11 @@ static bool test_RestoreGUID_ko(struct torture_context *tctx,
|
||||
torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Wrong error code");
|
||||
} else {
|
||||
struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED, "Get GUID");
|
||||
NT_STATUS_CONNECTION_DISCONNECTED, "Get GUID");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -916,8 +919,11 @@ static bool test_RestoreGUID_wrongversion(struct torture_context *tctx,
|
||||
torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Wrong error code on wrong version");
|
||||
} else {
|
||||
struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED, "Get GUID");
|
||||
NT_STATUS_CONNECTION_DISCONNECTED, "Get GUID");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -946,8 +952,11 @@ static bool test_RestoreGUID_wronguser(struct torture_context *tctx,
|
||||
torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_ACCESS, "Restore GUID");
|
||||
} else {
|
||||
struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED, "Get GUID");
|
||||
NT_STATUS_CONNECTION_DISCONNECTED, "Get GUID");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -977,8 +986,11 @@ static bool test_RestoreGUID_v3(struct torture_context *tctx,
|
||||
torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret");
|
||||
} else {
|
||||
struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED, "Get GUID");
|
||||
NT_STATUS_CONNECTION_DISCONNECTED, "Get GUID");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1010,8 +1022,11 @@ static bool test_RestoreGUID(struct torture_context *tctx,
|
||||
torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret");
|
||||
} else {
|
||||
struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED, "Get GUID");
|
||||
NT_STATUS_CONNECTION_DISCONNECTED, "Get GUID");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1040,8 +1055,11 @@ static bool test_RestoreGUID_badmagiconsecret(struct torture_context *tctx,
|
||||
torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Wrong error code while providing bad magic in secret");
|
||||
} else {
|
||||
struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED, "Get GUID");
|
||||
NT_STATUS_CONNECTION_DISCONNECTED, "Get GUID");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1070,8 +1088,11 @@ static bool test_RestoreGUID_emptyrequest(struct torture_context *tctx,
|
||||
torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Bad error code on wrong has in access check");
|
||||
} else {
|
||||
struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED, "Get GUID");
|
||||
NT_STATUS_CONNECTION_DISCONNECTED, "Get GUID");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1107,8 +1128,11 @@ static bool test_RestoreGUID_badcertguid(struct torture_context *tctx,
|
||||
}
|
||||
} else {
|
||||
struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED, "Get GUID");
|
||||
NT_STATUS_CONNECTION_DISCONNECTED, "Get GUID");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1137,8 +1161,11 @@ static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context *tctx,
|
||||
torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
|
||||
} else {
|
||||
struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED, "Get GUID");
|
||||
NT_STATUS_CONNECTION_DISCONNECTED, "Get GUID");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1167,8 +1194,11 @@ static bool test_RestoreGUID_badhashaccesscheck(struct torture_context *tctx,
|
||||
torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
|
||||
} else {
|
||||
struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED, "Get GUID");
|
||||
NT_STATUS_CONNECTION_DISCONNECTED, "Get GUID");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1367,9 +1397,12 @@ static bool test_RetrieveBackupKeyGUID_validate(struct torture_context *tctx,
|
||||
2048,
|
||||
"RSA Key doesn't have 2048 bits");
|
||||
} else {
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, r),
|
||||
NT_STATUS_ACCESS_DENIED,
|
||||
NT_STATUS_CONNECTION_DISCONNECTED,
|
||||
"Get GUID");
|
||||
}
|
||||
|
||||
@ -1409,9 +1442,12 @@ static bool test_ServerWrap_encrypt_decrypt(struct torture_context *tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, &r),
|
||||
"encrypt");
|
||||
} else {
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, &r),
|
||||
NT_STATUS_ACCESS_DENIED,
|
||||
NT_STATUS_CONNECTION_DISCONNECTED,
|
||||
"encrypt");
|
||||
return true;
|
||||
}
|
||||
@ -1501,9 +1537,12 @@ static bool test_ServerWrap_decrypt_wrong_keyGUID(struct torture_context *tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, &r),
|
||||
"encrypt");
|
||||
} else {
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, &r),
|
||||
NT_STATUS_ACCESS_DENIED,
|
||||
NT_STATUS_CONNECTION_DISCONNECTED,
|
||||
"encrypt");
|
||||
return true;
|
||||
}
|
||||
@ -1595,9 +1634,12 @@ static bool test_ServerWrap_decrypt_empty_request(struct torture_context *tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, &r),
|
||||
"encrypt");
|
||||
} else {
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, &r),
|
||||
NT_STATUS_ACCESS_DENIED,
|
||||
NT_STATUS_CONNECTION_DISCONNECTED,
|
||||
"encrypt");
|
||||
return true;
|
||||
}
|
||||
@ -1692,9 +1734,12 @@ static bool test_ServerWrap_decrypt_short_request(struct torture_context *tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, &r),
|
||||
"encrypt");
|
||||
} else {
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, &r),
|
||||
NT_STATUS_ACCESS_DENIED,
|
||||
NT_STATUS_CONNECTION_DISCONNECTED,
|
||||
"encrypt");
|
||||
return true;
|
||||
}
|
||||
@ -2104,9 +2149,12 @@ static bool test_ServerWrap_decrypt_wrong_stuff(struct torture_context *tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, &r),
|
||||
"encrypt");
|
||||
} else {
|
||||
if (!dcerpc_binding_handle_is_connected(b)) {
|
||||
torture_skip(tctx, "already disconnected");
|
||||
}
|
||||
torture_assert_ntstatus_equal(tctx,
|
||||
dcerpc_bkrp_BackupKey_r(b, tctx, &r),
|
||||
NT_STATUS_ACCESS_DENIED,
|
||||
NT_STATUS_CONNECTION_DISCONNECTED,
|
||||
"encrypt");
|
||||
return true;
|
||||
}
|
||||
|
@ -2993,9 +2993,11 @@ static bool test_overwrite_read_only_file(struct torture_context *tctx,
|
||||
struct smb2_tree *tree)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct smb2_create c;
|
||||
struct smb2_create c = {};
|
||||
struct smb2_create c2 = {};
|
||||
const char *fname = BASEDIR "\\test_overwrite_read_only_file.txt";
|
||||
struct smb2_handle handle = {{0}};
|
||||
struct smb2_handle h2 = {};
|
||||
union smb_fileinfo q;
|
||||
union smb_setfileinfo set;
|
||||
struct security_descriptor *sd = NULL, *sd_orig = NULL;
|
||||
@ -3007,17 +3009,26 @@ static bool test_overwrite_read_only_file(struct torture_context *tctx,
|
||||
int disposition;
|
||||
const char *disposition_string;
|
||||
NTSTATUS expected_status;
|
||||
} tcases[] = {
|
||||
};
|
||||
|
||||
#define TCASE(d, s) { \
|
||||
.disposition = d, \
|
||||
.disposition_string = #d, \
|
||||
.expected_status = s, \
|
||||
}
|
||||
|
||||
struct tcase fs_tcases[] = {
|
||||
TCASE(NTCREATEX_DISP_OPEN, NT_STATUS_OK),
|
||||
TCASE(NTCREATEX_DISP_SUPERSEDE, NT_STATUS_ACCESS_DENIED),
|
||||
TCASE(NTCREATEX_DISP_OVERWRITE, NT_STATUS_ACCESS_DENIED),
|
||||
TCASE(NTCREATEX_DISP_OVERWRITE_IF, NT_STATUS_ACCESS_DENIED),
|
||||
};
|
||||
|
||||
struct tcase sharing_tcases[] = {
|
||||
TCASE(NTCREATEX_DISP_SUPERSEDE, NT_STATUS_SHARING_VIOLATION),
|
||||
TCASE(NTCREATEX_DISP_OVERWRITE, NT_STATUS_SHARING_VIOLATION),
|
||||
TCASE(NTCREATEX_DISP_OVERWRITE_IF, NT_STATUS_SHARING_VIOLATION),
|
||||
};
|
||||
#undef TCASE
|
||||
|
||||
ret = smb2_util_setup_dir(tctx, tree, BASEDIR);
|
||||
@ -3075,12 +3086,12 @@ static bool test_overwrite_read_only_file(struct torture_context *tctx,
|
||||
smb2_util_close(tree, handle);
|
||||
ZERO_STRUCT(handle);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tcases); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(fs_tcases); i++) {
|
||||
torture_comment(tctx, "Verify open with %s disposition\n",
|
||||
tcases[i].disposition_string);
|
||||
fs_tcases[i].disposition_string);
|
||||
|
||||
c = (struct smb2_create) {
|
||||
.in.create_disposition = tcases[i].disposition,
|
||||
.in.create_disposition = fs_tcases[i].disposition,
|
||||
.in.desired_access = SEC_FILE_READ_DATA,
|
||||
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
|
||||
.in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
|
||||
@ -3091,7 +3102,7 @@ static bool test_overwrite_read_only_file(struct torture_context *tctx,
|
||||
status = smb2_create(tree, tctx, &c);
|
||||
smb2_util_close(tree, c.out.file.handle);
|
||||
torture_assert_ntstatus_equal_goto(
|
||||
tctx, status, tcases[i].expected_status, ret, done,
|
||||
tctx, status, fs_tcases[i].expected_status, ret, done,
|
||||
"smb2_create failed\n");
|
||||
};
|
||||
|
||||
@ -3121,11 +3132,108 @@ static bool test_overwrite_read_only_file(struct torture_context *tctx,
|
||||
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
|
||||
"smb2_setinfo_file failed\n");
|
||||
|
||||
smb2_util_close(tree, handle);
|
||||
status = smb2_util_close(tree, handle);
|
||||
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
|
||||
"smb2_util_close failed\n");
|
||||
ZERO_STRUCT(handle);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sharing_tcases); i++) {
|
||||
struct tcase *tcase = &sharing_tcases[i];
|
||||
|
||||
torture_comment(tctx, "Verify %s disposition\n",
|
||||
tcase->disposition_string);
|
||||
|
||||
torture_comment(tctx, "Read-nonly open file with SHARE_READ\n");
|
||||
|
||||
c = (struct smb2_create) {
|
||||
.in.desired_access = SEC_FILE_READ_DATA,
|
||||
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
|
||||
.in.share_access = NTCREATEX_SHARE_ACCESS_READ,
|
||||
.in.create_disposition = NTCREATEX_DISP_OPEN_IF,
|
||||
.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
|
||||
.in.fname = fname,
|
||||
};
|
||||
|
||||
status = smb2_create(tree, tctx, &c);
|
||||
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
|
||||
"smb2_create failed\n");
|
||||
handle = c.out.file.handle;
|
||||
|
||||
torture_comment(tctx, "A second open with %s must return %s\n",
|
||||
tcase->disposition_string, nt_errstr(tcase->expected_status));
|
||||
|
||||
c2 = (struct smb2_create) {
|
||||
.in.desired_access = SEC_FILE_READ_DATA,
|
||||
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
|
||||
.in.share_access = NTCREATEX_SHARE_ACCESS_READ,
|
||||
.in.create_disposition = tcase->disposition,
|
||||
.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
|
||||
.in.fname = fname,
|
||||
};
|
||||
|
||||
status = smb2_create(tree, tctx, &c2);
|
||||
torture_assert_ntstatus_equal_goto(tctx, status,
|
||||
tcase->expected_status,
|
||||
ret, done,
|
||||
"Wrong status code\n");
|
||||
|
||||
status = smb2_util_close(tree, handle);
|
||||
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
|
||||
"smb2_util_close failed\n");
|
||||
ZERO_STRUCT(handle);
|
||||
|
||||
torture_comment(tctx, "First open with %s\n",
|
||||
tcase->disposition_string);
|
||||
|
||||
c = (struct smb2_create) {
|
||||
.in.desired_access = SEC_FILE_READ_DATA,
|
||||
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
|
||||
.in.share_access = NTCREATEX_SHARE_ACCESS_READ,
|
||||
.in.create_disposition = tcase->disposition,
|
||||
.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
|
||||
.in.fname = fname,
|
||||
};
|
||||
|
||||
status = smb2_create(tree, tctx, &c);
|
||||
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
|
||||
"smb2_create failed\n");
|
||||
handle = c.out.file.handle;
|
||||
|
||||
torture_comment(tctx, "A second read-only open with SHARE_READ "
|
||||
"must work\n");
|
||||
|
||||
c = (struct smb2_create) {
|
||||
.in.desired_access = SEC_FILE_READ_DATA,
|
||||
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
|
||||
.in.share_access = NTCREATEX_SHARE_ACCESS_READ,
|
||||
.in.create_disposition = NTCREATEX_DISP_OPEN,
|
||||
.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS,
|
||||
.in.fname = fname,
|
||||
};
|
||||
|
||||
status = smb2_create(tree, tctx, &c);
|
||||
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
|
||||
"smb2_create failed\n");
|
||||
h2 = c.out.file.handle;
|
||||
|
||||
status = smb2_util_close(tree, handle);
|
||||
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
|
||||
"smb2_util_close failed\n");
|
||||
ZERO_STRUCT(handle);
|
||||
|
||||
status = smb2_util_close(tree, h2);
|
||||
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
|
||||
"smb2_util_close failed\n");
|
||||
ZERO_STRUCT(h2);
|
||||
}
|
||||
|
||||
done:
|
||||
smb2_util_close(tree, handle);
|
||||
if (!smb2_util_handle_empty(handle)) {
|
||||
smb2_util_close(tree, handle);
|
||||
}
|
||||
if (!smb2_util_handle_empty(h2)) {
|
||||
smb2_util_close(tree, h2);
|
||||
}
|
||||
smb2_util_unlink(tree, fname);
|
||||
smb2_deltree(tree, BASEDIR);
|
||||
return ret;
|
||||
|
@ -944,6 +944,7 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
notify.smb2.out.changes[0].action, \
|
||||
notify.smb2.in.completion_filter); \
|
||||
ret = false; \
|
||||
goto done; \
|
||||
} else if (notify.smb2.out.changes[0].action != Action) { \
|
||||
torture_result(torture, TORTURE_FAIL, \
|
||||
"ERROR: nchanges=%d action=%d " \
|
||||
@ -953,6 +954,7 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
Action, \
|
||||
notify.smb2.in.completion_filter); \
|
||||
ret = false; \
|
||||
goto done; \
|
||||
} else if (strcmp(notify.smb2.out.changes[0].name.s, \
|
||||
"tname1") != 0) { \
|
||||
torture_result(torture, TORTURE_FAIL, \
|
||||
@ -963,6 +965,7 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
notify.smb2.in.completion_filter, \
|
||||
notify.smb2.out.changes[0].name.s); \
|
||||
ret = false; \
|
||||
goto done; \
|
||||
} \
|
||||
} \
|
||||
} while (0); \
|
||||
@ -1016,14 +1019,12 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
torture_comment(torture, "Testing rename file\n");
|
||||
ZERO_STRUCT(sinfo);
|
||||
sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
|
||||
sinfo.rename_information.in.file.handle = h1;
|
||||
sinfo.rename_information.in.overwrite = true;
|
||||
sinfo.rename_information.in.root_fid = 0;
|
||||
sinfo.rename_information.in.new_name = BASEDIR_MSK "\\tname2";
|
||||
NOTIFY_MASK_TEST("Testing rename file",
|
||||
smb2_util_close(tree2, custom_smb2_create(tree2,
|
||||
torture, &(io1.smb2)));,
|
||||
smb2_setinfo_file(tree2, &sinfo);,
|
||||
torture_smb2_testfile(tree2, BASEDIR_MSK "\\tname1", &h2);,
|
||||
(sinfo.rename_information.in.file.handle = h2, smb2_setinfo_file(tree2, &sinfo));,
|
||||
smb2_util_unlink(tree2, BASEDIR_MSK "\\tname2");,
|
||||
NOTIFY_ACTION_OLD_NAME,
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME, 2);
|
||||
@ -1031,21 +1032,19 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
torture_comment(torture, "Testing rename dir\n");
|
||||
ZERO_STRUCT(sinfo);
|
||||
sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
|
||||
sinfo.rename_information.in.file.handle = h1;
|
||||
sinfo.rename_information.in.overwrite = true;
|
||||
sinfo.rename_information.in.root_fid = 0;
|
||||
sinfo.rename_information.in.new_name = BASEDIR_MSK "\\tname2";
|
||||
NOTIFY_MASK_TEST("Testing rename dir",
|
||||
smb2_util_mkdir(tree2, BASEDIR_MSK "\\tname1");,
|
||||
smb2_setinfo_file(tree2, &sinfo);,
|
||||
smb2_util_rmdir(tree2, BASEDIR_MSK "\\tname2");,
|
||||
torture_smb2_testdir(tree2, BASEDIR_MSK "\\tname1", &h2);,
|
||||
(sinfo.rename_information.in.file.handle = h2, smb2_setinfo_file(tree2, &sinfo));,
|
||||
(smb2_util_close(tree2, h2), smb2_util_rmdir(tree2, BASEDIR_MSK "\\tname2"));,
|
||||
NOTIFY_ACTION_OLD_NAME,
|
||||
FILE_NOTIFY_CHANGE_DIR_NAME, 2);
|
||||
|
||||
torture_comment(torture, "Testing set path attribute\n");
|
||||
NOTIFY_MASK_TEST("Testing set path attribute",
|
||||
smb2_util_close(tree2, custom_smb2_create(tree2,
|
||||
torture, &(io.smb2)));,
|
||||
torture_setup_simple_file(torture, tree2, BASEDIR_MSK "\\tname1");,
|
||||
smb2_util_setatr(tree2, BASEDIR_MSK "\\tname1",
|
||||
FILE_ATTRIBUTE_HIDDEN);,
|
||||
smb2_util_unlink(tree2, BASEDIR_MSK "\\tname1");,
|
||||
@ -1055,12 +1054,10 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
torture_comment(torture, "Testing set path write time\n");
|
||||
ZERO_STRUCT(sinfo);
|
||||
sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
|
||||
sinfo.generic.in.file.handle = h1;
|
||||
sinfo.basic_info.in.write_time = 1000;
|
||||
NOTIFY_MASK_TEST("Testing set path write time",
|
||||
smb2_util_close(tree2, custom_smb2_create(tree2,
|
||||
torture, &(io1.smb2)));,
|
||||
smb2_setinfo_file(tree2, &sinfo);,
|
||||
torture_setup_simple_file(torture, tree2, BASEDIR_MSK "\\tname1");,
|
||||
(sinfo.generic.in.file.handle = h2, smb2_setinfo_file(tree2, &sinfo));,
|
||||
smb2_util_unlink(tree2, BASEDIR_MSK "\\tname1");,
|
||||
NOTIFY_ACTION_MODIFIED,
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE, 1);
|
||||
@ -1073,13 +1070,12 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
else {
|
||||
ZERO_STRUCT(sinfo);
|
||||
sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
|
||||
sinfo.generic.in.file.handle = h1;
|
||||
sinfo.basic_info.in.create_time = 0;
|
||||
torture_comment(torture, "Testing set file create time\n");
|
||||
NOTIFY_MASK_TEST("Testing set file create time",
|
||||
smb2_create_complex_file(torture, tree2,
|
||||
BASEDIR_MSK "\\tname1", &h2);,
|
||||
smb2_setinfo_file(tree2, &sinfo);,
|
||||
(sinfo.generic.in.file.handle = h2, smb2_setinfo_file(tree2, &sinfo));,
|
||||
(smb2_util_close(tree2, h2),
|
||||
smb2_util_unlink(tree2, BASEDIR_MSK "\\tname1"));,
|
||||
NOTIFY_ACTION_MODIFIED,
|
||||
@ -1088,7 +1084,6 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
|
||||
ZERO_STRUCT(sinfo);
|
||||
sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
|
||||
sinfo.generic.in.file.handle = h1;
|
||||
sinfo.basic_info.in.access_time = 0;
|
||||
torture_comment(torture, "Testing set file access time\n");
|
||||
NOTIFY_MASK_TEST("Testing set file access time",
|
||||
@ -1096,7 +1091,7 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
tree2,
|
||||
BASEDIR_MSK "\\tname1",
|
||||
&h2);,
|
||||
smb2_setinfo_file(tree2, &sinfo);,
|
||||
(sinfo.generic.in.file.handle = h2, smb2_setinfo_file(tree2, &sinfo));,
|
||||
(smb2_util_close(tree2, h2),
|
||||
smb2_util_unlink(tree2, BASEDIR_MSK "\\tname1"));,
|
||||
NOTIFY_ACTION_MODIFIED,
|
||||
@ -1104,7 +1099,6 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
|
||||
ZERO_STRUCT(sinfo);
|
||||
sinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
|
||||
sinfo.generic.in.file.handle = h1;
|
||||
sinfo.basic_info.in.change_time = 0;
|
||||
torture_comment(torture, "Testing set file change time\n");
|
||||
NOTIFY_MASK_TEST("Testing set file change time",
|
||||
@ -1112,7 +1106,7 @@ static bool torture_smb2_notify_mask(struct torture_context *torture,
|
||||
tree2,
|
||||
BASEDIR_MSK "\\tname1",
|
||||
&h2);,
|
||||
smb2_setinfo_file(tree2, &sinfo);,
|
||||
(sinfo.generic.in.file.handle = h2, smb2_setinfo_file(tree2, &sinfo));,
|
||||
(smb2_util_close(tree2, h2),
|
||||
smb2_util_unlink(tree2, BASEDIR_MSK "\\tname1"));,
|
||||
NOTIFY_ACTION_MODIFIED,
|
||||
|
10
third_party/heimdal/lib/gssapi/krb5/8003.c
vendored
10
third_party/heimdal/lib/gssapi/krb5/8003.c
vendored
@ -239,6 +239,16 @@ _gsskrb5_verify_8003_checksum(
|
||||
_gss_mg_decode_le_uint32(p, flags);
|
||||
p += 4;
|
||||
|
||||
/*
|
||||
* Sometimes Windows clients forget
|
||||
* to set GSS_C_MUTUAL_FLAG together
|
||||
* with GSS_C_DCE_STYLE, but
|
||||
* DCE_STYLE implies mutual authentication
|
||||
*/
|
||||
if (*flags & GSS_C_DCE_STYLE) {
|
||||
*flags |= GSS_C_MUTUAL_FLAG;
|
||||
}
|
||||
|
||||
if (cksum->checksum.length > 24 && (*flags & GSS_C_DELEG_FLAG)) {
|
||||
if(cksum->checksum.length < 28) {
|
||||
*minor_status = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user