1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-11 16:58:40 +03:00

Compare commits

...

35 Commits

Author SHA1 Message Date
Stefan Metzmacher
cc3a119585 s3:winbindd: call process_set_title() for locator child
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15749

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>

Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Thu Oct 31 14:02:39 UTC 2024 on atb-devel-224

(cherry picked from commit e4e3f05cd7d6fdc98a24f592a099f7d24136788d)

Autobuild-User(v4-20-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-20-test): Thu Nov  7 13:39:23 UTC 2024 on atb-devel-224
2024-11-07 13:39:23 +00:00
Stefan Metzmacher
81f92c8a62 third_party/heimdal: Import lorikeet-heimdal-202410161454 (commit 0d61538a16b5051c820702f0711102112cd01a83)
gsskrb5: let GSS_C_DCE_STYLE imply GSS_C_MUTUAL_FLAG as acceptor

Windows clients forget GSS_C_MUTUAL_FLAG in some situations where they
use GSS_C_DCE_STYLE, in the assumption that GSS_C_MUTUAL_FLAG is
implied.

Both Windows and MIT as server already imply GSS_C_MUTUAL_FLAG
when GSS_C_DCE_STYLE is used.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15740
PR: https://github.com/heimdal/heimdal/pull/1266

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>

Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Wed Oct 16 19:05:15 UTC 2024 on atb-devel-224

(cherry picked from commit ce10b28566eb7b3e26a1e404b278d3d761ac183e)

Autobuild-User(v4-20-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-20-test): Thu Nov  7 09:21:35 UTC 2024 on atb-devel-224
2024-11-07 09:21:35 +00:00
Ralph Boehme
6bcccb5c7b smbd: fix sharing access check for directories
This was missing from commit 6140c3177a0330f42411618c3fca28930ea02a21 and causes
all opens of directories to be handled as stat opens, bypassing the sharemode
check.

Not adding a test at this time, as my (hopefully) soon to be merged Directory
Leases branch has a test which actually detected this problem.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15732

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit 20206a335a6af71b99f6441df145feea6563cf5a)
2024-11-07 08:18:17 +00:00
Ralph Boehme
3572ffa6c5 smbd: fix share access check for overwrite dispostions
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15732

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>

Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Mon Oct 14 12:23:04 UTC 2024 on atb-devel-224

(cherry picked from commit 6140c3177a0330f42411618c3fca28930ea02a21)
2024-11-07 08:18:17 +00:00
Ralph Boehme
2c7f99a68c smbtorture: add subtests for overwrite dispositions vs sharemodes
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15732

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit 849afe05ade140898b1eab9b28d46edc8357c844)
2024-11-07 08:18:17 +00:00
Ralph Boehme
dca5bd464d smbtorture: fix smb2.notify.mask test
The strange function custom_smb2_create() was somehow causing
NT_STATUS_DELETE_PENDING failures:

  failure: mask [
  (../../source4/torture/smb2/notify.c:490) Incorrect status NT_STATUS_DELETE_PENDING - should be NT_STATUS_OK
  ]

I couldn't figure out what was causing this exactly, but after doing these
cleanups the error went away.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15732

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit 4591f27ca81dff997ef7474565fc9c373abfa4a9)
2024-11-07 08:18:17 +00:00
Ralph Boehme
d618552669 smbtorture: prepare test_overwrite_read_only_file() for more subtests
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15732

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit f88e52a6f487a216dbb805fabc08e862abb9b643)
2024-11-07 08:18:17 +00:00
Stefan Metzmacher
1a74def369 dcesrv_core: better fault codes dcesrv_auth_prepare_auth3()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>

Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Thu Oct 10 15:17:46 UTC 2024 on atb-devel-224

(cherry picked from commit 9263ce5752063235836d5f77220b0151df6c9408)
2024-11-07 08:18:17 +00:00
Stefan Metzmacher
bef660cfee dcesrv_core: fix the auth3 for large ntlmssp messages
I know finding any real logic in reading the patch,
doesn't really show what's going on. I tried hard
to simplify it, but this is the only way I found
that fixed the test_auth_pad_ntlm_2889_auth3 test
without breaking other tests...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 8b8e4ff1b19ba06821d774d0e1a8b1cad7f06120)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
70889a5f2f gensec:spnego: ignore trailing bytes in SPNEGO_SERVER_START state
This matches Windows (at least Server 2012_R2).

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 86808d66f30136850f857b749e768c88de3a079f)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
a7742b3519 gensec:ntlmssp: only allow messages up to 2888 bytes
This matches Windows (at least Server 2012_R2).

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 55dd8bdb05b4e814beb50d11a6f12c94e5f6e9d5)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
fd7bfa6ad2 dcesrv_core: alter_context logon failures should result in DCERPC_FAULT_ACCESS_DENIED
We should use DCERPC_FAULT_ACCESS_DENIED as default for
gensec status results of e.g. NT_STATUS_LOGON_FAILURE or
NT_STATUS_INVALID_PARAMTER.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 31a422b7e58d7a670ebedb7c91f240a3134a9624)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
b6dd675372 dcesrv_core: a failure from gensec_update results in NAK_REASON_INVALID_CHECKSUM
We already report that for gensec_start_mech_by_authtype() failures,
but we also need to do that for any invalid authentication.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 97545873ebc2daf9c3daee914a90687625a08225)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
6309b9a770 dcerpc_util: let dcerpc_pull_auth_trailer() ignore data_and_pad for bind, alter, auth3
Sometimes Windows sends 3 presentation contexts (NDR32, NDR64,
BindTimeFeatureNegotiation) in the first BIND of an association.

Binding an additional connection to the association seems to
reuse the BIND buffer and just changes the num_contexts field from
3 to 2 and leaves the BindTimeFeatureNegotiation context as padding
in places.

Note, the auth_pad_length field is send as 0 in that case,
which means we need to ignore it completely, as well as any
padding before the auth header.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 85b2dcd93848a590727dac243e8eb3614be75fad)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
8c33f14b97 dcerpc_util: let dcerpc_pull_auth_trailer() expose the reject reason
If dcerpc_pull_auth_trailer() returns NT_STATUS_RPC_PROTOCOL_ERROR
it will return the BIND reject code in auth->auth_context_id.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 7a6a1aae6fa74ab0f55c1160aedd2d79c9a44a90)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
1dbcb533af dcerpc_util: let dcerpc_pull_auth_trailer() check that auth_offset is 4 bytes aligned
That what Windows also asserts.

It also makes sure that ndr_pull_dcerpc_auth() will
start with ndr->offset = 0 and don't tries to eat
possible padding.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 890fff1ca0c4e1eb8ef26c4f88aa18aeda3afc4f)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
432f8a3b69 tests/dcerpc/raw_protocol: test invalid schannel binds
Note the ad_member will keep these as expected failures,
as it doesn't provide the netlogon service,
while the knownfail for the ADDC is only temporary.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit f7a3827010a859839a3ae7d0cdf297a15610d286)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
5efc2a0ea9 tests/dcerpc/raw_protocol: add more tests for auth_pad alignment
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 0bc562eb26cad3a5cb8da2da54db86932791f3de)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
a6dec953e7 tests/dcerpc/raw_protocol: add tests for max auth_padding, auth_len or auth_offset
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 0da9e4d7430c7dbb37783e6152f7672bf29498e9)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
7185f30946 tests/dcerpc/raw_protocol: fix comment in test_spnego_change_auth_type1
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 7b5c3f9b1f334eb9d7906338e2e64196a6530068)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
d896ce18e0 tests/dcerpc/raw_protocol: test_no_auth_ctx_request
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 57fb07f5a3369d679f8918f853303b56e58dfb3d)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
fd6e9855c3 dcesrv_core: introduce dcesrv_connection->transport_max_recv_frag
The max fragment size depends on the transport.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 09e8dd23ce0c08c5c04bd74121f3664f420af877)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
71aad11c2c tests/dcerpc/raw_protocol: run test_neg_xmit_ffff_ffff over tcp and smb
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit a2d894fd37aaa9bce64ad95e01412681a08790ea)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
7bd44b9fb0 dcesrv_core: add more verbose debugging for missing association groups
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit ac5818f2dd348e61b4be35505bee00b330ec4450)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
8d902a2003 RawDCERPCTest: add some more auth_length related asserts
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit bb8ad1f22924b581bfb66555713e98efa91372b2)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
f2705e5b3b RawDCERPCTest: split prepare_pdu() and send_pdu_blob() out of send_pdu()
This will make it possible to alter pdus before sending them to the
server.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 444f9c6624f5c997dfdc4ae0bfb8823a56fbef70)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
d921255c84 s4:librpc: provide py_schannel bindings
This will be used in the dcerpc.raw_protocol test.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 0acbbeab4db0c8bc8ff655d652e249fecb3c4ef9)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
5e2aa6bf03 dcerpc_util: don't allow auth_padding for BIND, ALTER_CONTEXT and AUTH3 pdus
This is how Windows 2022 (and 2025 preview) behaves...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit be02d4077db1d6c35b2e480937a04b5e70545a6d)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
0c7983db19 tests/dcerpc/raw_protocol: add more test for auth padding during ALTER_CONTEXT/AUTH3
The aim is to keep testing the code paths, which are no longer
testing because allow_bind_auth_pad is false now, which
means the existing tests fail directly at the BIND,
but we also want to test the error handling on
ALTER_CONTEXT (and AUTH3).

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 9309283ddbcc60cb8dac8ecd3f4bcecfbf8ac732)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
8ee66862db dcesrv_core: return NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED for binds without contexts
This is the error Windows 2022 (and 2025 preview) return.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 8e6696b2ac6990f3d6bac804c9a0f1a2b8f0ada0)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
74b127d037 dcesrv_core: disconnect after a fault with non AUTH_LEVEL_CONNECT bind
Without an auth context using DCERPC_AUTH_LEVEL_PACKET or higher
the fault to reject requests with an invalid auth level
should trigger a disconnect after sending the fault to
the client.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 31c2f35bba003daee39756e83def0f3d45c19c6b)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
d095ad71cc s4:selftest: only run ad_member with AUTH_LEVEL_CONNECT_LSA=1
We only want to test against
'allow dcerpc auth level connect:lsarpc = yes' once
in order to have the related code tests.
We use the ad_memeber for that special test and
use the default on the tested ADDC.

This reveals some knownfails, which will be fixed in
the next commit...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 93bd5ba609f93ce8298f12f2a7b0ad333e0f48bf)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
c063734ac3 tests/dcerpc/raw_protocol: pass against Windows 2022 and require special env vars for legacy servers
Test works against Windows 2022 and works like this:

SMB_CONF_PATH=/dev/null SERVER=172.31.9.118 \
  TARGET_HOSTNAME=w2022-118.w2022-l7.base IGNORE_RANDOM_PAD=1 \
  DOMAIN=W2022-L7 REALM=W2022-L7.BASE \
  USERNAME=administrator PASSWORD=A1b2C3d4 \
  python/samba/tests/dcerpc/raw_protocol.py -v -f TestDCERPC_BIND

Against a legacy Windows2012R2 server this still works:

SMB_CONF_PATH=/dev/null SERVER=172.31.9.188 \
  TARGET_HOSTNAME=w2012r2-188.w2012r2-l6.base ALLOW_BIND_AUTH_PAD=1 \
  LEGACY_BIND_NACK_NO_REASON=1 AUTH_LEVEL_CONNECT_LSA=1 \
  IGNORE_RANDOM_PAD=1 DOMAIN=W2012R2-L6 REALM=W2012R2-L6.BASE \
  USERNAME=administrator PASSWORD=A1b2C3d4 \
  python/samba/tests/dcerpc/raw_protocol.py -v -f TestDCERPC_BIND

Currently Samba behaves like 2012R2, but the next commits
will change that...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 98d908bfd07283878a7a6a630c2bfe5d27b5ffd8)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
b647d52691 RawDCERPCTest: ignore errors in smb_pipe_socket.close()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit b51ab42284211981a1ee6c8865845c7dfc985cb4)
2024-11-07 08:18:16 +00:00
Stefan Metzmacher
2d2d5f675d s4:tortore/rpc: let rpc.backupkey without privacy pass against Windows 2022
The server disconnects after the first fault.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14356

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 8c6b5b87434e96d4cb695c0a5cf8aa0a0472c6a4)
2024-11-07 08:18:16 +00:00
24 changed files with 1839 additions and 185 deletions

View File

@ -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;
}

View File

@ -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));

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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\)

View 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\)

View File

@ -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

View File

@ -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,

View File

@ -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. */

View File

@ -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;

View File

@ -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 */

View File

@ -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),

View File

@ -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"'],

View File

@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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;