summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/gensec/gensec_gssapi.c14
-rw-r--r--source4/heimdal/lib/gssapi/krb5/accept_sec_context.c22
-rw-r--r--source4/heimdal/lib/krb5/rd_req.c3
-rw-r--r--source4/libcli/raw/smb.h27
-rw-r--r--source4/libcli/smb2/connect.c8
-rw-r--r--source4/libcli/smb2/signing.c6
-rw-r--r--source4/libcli/smb2/smb2.h4
-rw-r--r--source4/libcli/smb2/transport.c24
-rw-r--r--source4/librpc/idl/krb5pac.idl6
-rw-r--r--source4/ntvfs/ntvfs_generic.c10
-rw-r--r--source4/ntvfs/posix/pvfs_open.c14
-rwxr-xr-xsource4/pidl/tests/samba3-cli.pl2
-rw-r--r--source4/smb_server/smb2/receive.c46
-rw-r--r--source4/smb_server/smb2/smb2_server.h2
-rw-r--r--source4/torture/auth/pac.c97
-rw-r--r--source4/torture/nbt/winsreplication.c12
-rw-r--r--source4/torture/raw/open.c44
-rw-r--r--source4/torture/smb2/create.c101
18 files changed, 312 insertions, 130 deletions
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 0df40dc82f..20d08078be 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -1236,12 +1236,16 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit
return NT_STATUS_NO_USER_SESSION_KEY;
}
- DEBUG(10, ("Got KRB5 session key of length %d\n",
- (int)KRB5_KEY_LENGTH(subkey)));
- gensec_gssapi_state->session_key = data_blob_talloc(gensec_gssapi_state,
- KRB5_KEY_DATA(subkey), KRB5_KEY_LENGTH(subkey));
+ DEBUG(10, ("Got KRB5 session key of length %d%s\n",
+ (int)KRB5_KEY_LENGTH(subkey),
+ (gensec_gssapi_state->sasl_state == STAGE_DONE)?" (done)":""));
+ *session_key = data_blob_talloc(gensec_gssapi_state,
+ KRB5_KEY_DATA(subkey), KRB5_KEY_LENGTH(subkey));
krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, subkey);
- *session_key = gensec_gssapi_state->session_key;
+ if (gensec_gssapi_state->sasl_state == STAGE_DONE) {
+ /* only cache in the done stage */
+ gensec_gssapi_state->session_key = *session_key;
+ }
dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
return NT_STATUS_OK;
diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
index 8dbd087da6..a6f0f31246 100644
--- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
@@ -520,16 +520,30 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
if(ctx->flags & GSS_C_MUTUAL_FLAG) {
krb5_data outbuf;
+ int use_subkey = 0;
_gsskrb5i_is_cfx(ctx, &is_cfx);
if (is_cfx != 0
|| (ap_options & AP_OPTS_USE_SUBKEY)) {
- kret = krb5_auth_con_addflags(context,
- ctx->auth_context,
- KRB5_AUTH_CONTEXT_USE_SUBKEY,
- NULL);
+ use_subkey = 1;
+ } else {
+ krb5_keyblock *rkey;
+ kret = krb5_auth_con_getremotesubkey(context, ctx->auth_context, &rkey);
+ if (kret == 0) {
+ kret = krb5_auth_con_setlocalsubkey(context, ctx->auth_context, rkey);
+ if (kret == 0) {
+ use_subkey = 1;
+ }
+ krb5_free_keyblock(context, rkey);
+ }
+ }
+ if (use_subkey) {
ctx->more_flags |= ACCEPTOR_SUBKEY;
+ krb5_auth_con_addflags(context,
+ ctx->auth_context,
+ KRB5_AUTH_CONTEXT_USE_SUBKEY,
+ NULL);
}
kret = krb5_mk_rep(context,
diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c
index e80aaa6789..ddf1f69ae4 100644
--- a/source4/heimdal/lib/krb5/rd_req.c
+++ b/source4/heimdal/lib/krb5/rd_req.c
@@ -463,8 +463,6 @@ krb5_verify_ap_req2(krb5_context context,
ac->keytype = ETYPE_NULL;
-#if 0
-/* it's bad to use a different enctype as the client */
if (etypes.val) {
int i;
@@ -475,7 +473,6 @@ krb5_verify_ap_req2(krb5_context context,
}
}
}
-#endif
/* save key */
ret = krb5_copy_keyblock(context, &t->ticket.key, &ac->keyblock);
diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h
index 8663792f78..d4091acf48 100644
--- a/source4/libcli/raw/smb.h
+++ b/source4/libcli/raw/smb.h
@@ -167,17 +167,30 @@
#define NTCREATEX_OPTIONS_NO_RECALL 0x00400000
/* Must be ignored by the server, per MS-SMB 2.2.8 */
#define NTCREATEX_OPTIONS_FREE_SPACE_QUERY 0x00800000
-/* create options these bits are for private use by backends, they are
- not valid on the wire */
-#define NTCREATEX_OPTIONS_PRIVATE_MASK 0xFF000000
-#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x01000000
-#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x02000000
-#define NTCREATEX_OPTIONS_MUST_IGNORE_MASK ( NTCREATEX_OPTIONS_TREE_CONNECTION | NTCREATEX_OPTIONS_COMPLETE_IF_OPLOCKED | NTCREATEX_OPTIONS_OPEN_FOR_RECOVERY | NTCREATEX_OPTIONS_FREE_SPACE_QUERY | NTCREATEX_OPTIONS_OPFILTER )
+#define NTCREATEX_OPTIONS_MUST_IGNORE_MASK (NTCREATEX_OPTIONS_TREE_CONNECTION | \
+ NTCREATEX_OPTIONS_OPEN_FOR_RECOVERY | \
+ NTCREATEX_OPTIONS_FREE_SPACE_QUERY | \
+ 0x000F0000)
-#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK (0x000F0000 | NTCREATEX_OPTIONS_OPEN_BY_FILE_ID)
+#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK (NTCREATEX_OPTIONS_OPEN_BY_FILE_ID)
+#define NTCREATEX_OPTIONS_INVALID_PARAM_MASK (NTCREATEX_OPTIONS_OPFILTER | \
+ NTCREATEX_OPTIONS_SYNC_ALERT | \
+ NTCREATEX_OPTIONS_ASYNC_ALERT | \
+ NTCREATEX_OPTIONS_OPFILTER | \
+ 0xFF000000)
+/*
+ * We reuse some ignored flags for private use.
+ * This values have different meaning for some ntvfs backends.
+ *
+ * TODO: use values that are ignore for sure...
+ */
+#define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS 0x00010000
+#define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB 0x00020000
+#define NTCREATEX_OPTIONS_PRIVATE_MASK (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | \
+ NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)
/* ntcreatex impersonation field */
#define NTCREATEX_IMPERSONATION_ANONYMOUS 0
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index c89c109b72..43151943d3 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -115,13 +115,19 @@ static void continue_negprot(struct smb2_request *req)
transport->signing_required = false;
break;
case SMB_SIGNING_SUPPORTED:
- case SMB_SIGNING_AUTO:
if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
transport->signing_required = true;
} else {
transport->signing_required = false;
}
break;
+ case SMB_SIGNING_AUTO:
+ if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) {
+ transport->signing_required = true;
+ } else {
+ transport->signing_required = false;
+ }
+ break;
case SMB_SIGNING_REQUIRED:
if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) {
transport->signing_required = true;
diff --git a/source4/libcli/smb2/signing.c b/source4/libcli/smb2/signing.c
index 0d655d1a86..de9e1e9d29 100644
--- a/source4/libcli/smb2/signing.c
+++ b/source4/libcli/smb2/signing.c
@@ -94,12 +94,6 @@ NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session
return NT_STATUS_OK;
}
- if (session_key.length == 0) {
- DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
- (unsigned)session_key.length));
- return NT_STATUS_ACCESS_DENIED;
- }
-
memcpy(sig, buf->hdr+SMB2_HDR_SIGNATURE, 16);
memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16);
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index 5d6341a15b..f00107de60 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -276,7 +276,9 @@ struct smb2_request {
#define SMB2_CREATE_TAG_TWRP "TWrp"
#define SMB2_CREATE_TAG_QFID "QFid"
-
+/* SMB2 Create ignore some more create_options */
+#define SMB2_CREATE_OPTIONS_NOT_SUPPORTED_MASK (NTCREATEX_OPTIONS_TREE_CONNECTION | \
+ NTCREATEX_OPTIONS_OPFILTER)
/*
check that a body has the expected size
diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c
index d9691bec7c..b946a102c8 100644
--- a/source4/libcli/smb2/transport.c
+++ b/source4/libcli/smb2/transport.c
@@ -235,6 +235,17 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE);
req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS));
+ if ((flags & SMB2_HDR_FLAG_ASYNC) &&
+ NT_STATUS_EQUAL(req->status, STATUS_PENDING)) {
+ req->cancel.can_cancel = true;
+ req->cancel.pending_id = IVAL(hdr, SMB2_HDR_PID);
+ for (i=0; i< req->cancel.do_cancel; i++) {
+ smb2_cancel(req);
+ }
+ talloc_free(buffer);
+ return NT_STATUS_OK;
+ }
+
if (req->session && req->session->signing_active) {
status = smb2_check_signature(&req->in,
req->session->session_key);
@@ -244,19 +255,6 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
return status;
}
}
-
-
- if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) {
- if (flags & 0x00000002) {
- req->cancel.can_cancel = true;
- req->cancel.pending_id = IVAL(hdr, SMB2_HDR_PID);
- for (i=0; i< req->cancel.do_cancel; i++) {
- smb2_cancel(req);
- }
- }
- talloc_free(buffer);
- return NT_STATUS_OK;
- }
buffer_code = SVAL(req->in.body, 0);
req->in.body_fixed = (buffer_code & ~1);
diff --git a/source4/librpc/idl/krb5pac.idl b/source4/librpc/idl/krb5pac.idl
index 3505fc895c..b450908915 100644
--- a/source4/librpc/idl/krb5pac.idl
+++ b/source4/librpc/idl/krb5pac.idl
@@ -70,7 +70,11 @@ interface krb5pac
[case(PAC_TYPE_SRV_CHECKSUM)] PAC_SIGNATURE_DATA srv_cksum;
[case(PAC_TYPE_KDC_CHECKSUM)] PAC_SIGNATURE_DATA kdc_cksum;
[case(PAC_TYPE_LOGON_NAME)] PAC_LOGON_NAME logon_name;
- [case(PAC_TYPE_UNKNOWN_12)] [subcontext(0)] DATA_BLOB_REM unknown;
+ /* when new PAC info types are added they are supposed to be done
+ in such a way that they are backwards compatible with existing
+ servers. This makes it safe to just use a [default] for
+ unknown types, which lets us ignore the data */
+ [default] [subcontext(0)] DATA_BLOB_REM unknown;
/* [case(PAC_TYPE_UNKNOWN_12)] PAC_UNKNOWN_12 unknown; */
} PAC_INFO;
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index 4f3a7e2198..c34bb7125e 100644
--- a/source4/ntvfs/ntvfs_generic.c
+++ b/source4/ntvfs/ntvfs_generic.c
@@ -532,16 +532,14 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs,
}
/* we need to check these bits before we check the private mask */
- if (io2->generic.in.create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) {
+ if (io2->generic.in.create_options & SMB2_CREATE_OPTIONS_NOT_SUPPORTED_MASK) {
status = NT_STATUS_NOT_SUPPORTED;
break;
}
- /* we use a couple of bits of the create options internally */
- if (io2->generic.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) {
- status = NT_STATUS_INVALID_PARAMETER;
- break;
- }
+ /* TODO: find out why only SMB2 ignores these */
+ io2->generic.in.create_options &= ~NTCREATEX_OPTIONS_SYNC_ALERT;
+ io2->generic.in.create_options &= ~NTCREATEX_OPTIONS_ASYNC_ALERT;
status = ntvfs->ops->open(ntvfs, req, io2);
break;
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 6114b2052c..c127885a68 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -1181,6 +1181,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
int fd;
struct odb_lock *lck;
uint32_t create_options;
+ uint32_t create_options_must_ignore_mask;
uint32_t share_access;
uint32_t access_mask;
uint32_t create_action = NTCREATEX_ACTION_EXISTED;
@@ -1206,13 +1207,22 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INVALID_PARAMETER;
}
- /* These options are ignored */
- create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
+ /*
+ * These options are ignored,
+ * but we reuse some of them as private values for the generic mapping
+ */
+ create_options_must_ignore_mask = NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
+ create_options_must_ignore_mask &= ~NTCREATEX_OPTIONS_PRIVATE_MASK;
+ create_options &= ~create_options_must_ignore_mask;
if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) {
return NT_STATUS_NOT_SUPPORTED;
}
+ if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
/* TODO: When we implement HSM, add a hook here not to pull
* the actual file off tape, when this option is passed from
* the client */
diff --git a/source4/pidl/tests/samba3-cli.pl b/source4/pidl/tests/samba3-cli.pl
index 80725d28cf..d762954159 100755
--- a/source4/pidl/tests/samba3-cli.pl
+++ b/source4/pidl/tests/samba3-cli.pl
@@ -44,7 +44,6 @@ is($x->{res},
status = cli_do_rpc_ndr(cli,
mem_ctx,
- PI_FOO,
&ndr_table_foo,
NDR_BAR,
&r);
@@ -89,7 +88,6 @@ is($x->{res},
status = cli_do_rpc_ndr(cli,
mem_ctx,
- PI_FOO,
&ndr_table_foo,
NDR_BAR,
&r);
diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c
index cfd6c1d01a..1fe6f0b877 100644
--- a/source4/smb_server/smb2/receive.c
+++ b/source4/smb_server/smb2/receive.c
@@ -79,12 +79,12 @@ struct smb2srv_request *smb2srv_init_request(struct smbsrv_connection *smb_conn)
NTSTATUS smb2srv_setup_reply(struct smb2srv_request *req, uint16_t body_fixed_size,
bool body_dynamic_present, uint32_t body_dynamic_size)
{
- uint32_t flags = 0x00000001;
+ uint32_t flags = SMB2_HDR_FLAG_REDIRECT;
uint32_t pid = IVAL(req->in.hdr, SMB2_HDR_PID);
uint32_t tid = IVAL(req->in.hdr, SMB2_HDR_TID);
if (req->pending_id) {
- flags |= 0x00000002;
+ flags |= SMB2_HDR_FLAG_ASYNC;
pid = req->pending_id;
tid = 0;
}
@@ -236,7 +236,7 @@ void smb2srv_send_reply(struct smb2srv_request *req)
}
/* if signing is active on the session then sign the packet */
- if (req->session && req->session->smb2_signing.active) {
+ if (req->is_signed) {
status = smb2_sign_message(&req->out,
req->session->session_info->session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -310,12 +310,7 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req)
if (!req->session) goto nosession;
- if (!req->session->smb2_signing.active) {
- /* TODO: workout the correct error code */
- smb2srv_send_error(req, NT_STATUS_FOOBAR);
- return NT_STATUS_OK;
- }
-
+ req->is_signed = true;
status = smb2_check_signature(&req->in,
req->session->session_info->session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -511,6 +506,8 @@ static NTSTATUS smb2srv_init_pending(struct smbsrv_connection *smb_conn)
NTSTATUS smb2srv_queue_pending(struct smb2srv_request *req)
{
+ NTSTATUS status;
+ bool signing_used = false;
int id;
if (req->pending_id) {
@@ -526,10 +523,35 @@ NTSTATUS smb2srv_queue_pending(struct smb2srv_request *req)
DLIST_ADD_END(req->smb_conn->requests2.list, req, struct smb2srv_request *);
req->pending_id = id;
+ if (req->smb_conn->connection->event.fde == NULL) {
+ /* the socket has been destroyed - no point trying to send an error! */
+ return NT_STATUS_REMOTE_DISCONNECT;
+ }
+
talloc_set_destructor(req, smb2srv_request_deny_destructor);
- smb2srv_send_error(req, STATUS_PENDING);
- talloc_set_destructor(req, smb2srv_request_destructor);
+ status = smb2srv_setup_reply(req, 8, true, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ SIVAL(req->out.hdr, SMB2_HDR_STATUS, NT_STATUS_V(STATUS_PENDING));
+
+ SSVAL(req->out.body, 0x02, 0);
+ SIVAL(req->out.body, 0x04, 0);
+
+ /* if the real reply will be signed set the signed flags, but don't sign */
+ if (req->is_signed) {
+ SIVAL(req->out.hdr, SMB2_HDR_FLAGS, IVAL(req->out.hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED);
+ signing_used = req->is_signed;
+ req->is_signed = false;
+ }
+
+ smb2srv_send_reply(req);
+
+ req->is_signed = signing_used;
+
+ talloc_set_destructor(req, smb2srv_request_destructor);
return NT_STATUS_OK;
}
@@ -545,7 +567,7 @@ void smb2srv_cancel_recv(struct smb2srv_request *req)
flags = IVAL(req->in.hdr, SMB2_HDR_FLAGS);
pending_id = IVAL(req->in.hdr, SMB2_HDR_PID);
- if (!(flags & 0x00000002)) {
+ if (!(flags & SMB2_HDR_FLAG_ASYNC)) {
/* TODO: what to do here? */
goto done;
}
diff --git a/source4/smb_server/smb2/smb2_server.h b/source4/smb_server/smb2/smb2_server.h
index ae4abbd71e..d45e0861af 100644
--- a/source4/smb_server/smb2/smb2_server.h
+++ b/source4/smb_server/smb2/smb2_server.h
@@ -62,6 +62,8 @@ struct smb2srv_request {
uint8_t _chained_file_handle[16];
uint8_t *chained_file_handle;
+ bool is_signed;
+
struct smb2_request_buffer in;
struct smb2_request_buffer out;
};
diff --git a/source4/torture/auth/pac.c b/source4/torture/auth/pac.c
index 7fdd7e58bf..4e51c66950 100644
--- a/source4/torture/auth/pac.c
+++ b/source4/torture/auth/pac.c
@@ -279,7 +279,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
struct auth_serversupplied_info *server_info_out;
krb5_keyblock server_keyblock;
- krb5_keyblock krbtgt_keyblock;
+ krb5_keyblock krbtgt_keyblock, *krbtgt_keyblock_p;
struct samr_Password *krbtgt_bytes, *krbsrv_bytes;
krb5_error_code ret;
@@ -309,9 +309,13 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
/* The krbtgt key in use when the above PAC was generated.
* This is an arcfour-hmac-md5 key, extracted with our 'net
* samdump' tool. */
- krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
- if (!krbtgt_bytes) {
- torture_fail(tctx, "(saved test) Could not interpret krbtgt key");
+ if (*pac_kdc_key == 0) {
+ krbtgt_bytes = NULL;
+ } else {
+ krbtgt_bytes = smbpasswd_gethexpwd(mem_ctx, pac_kdc_key);
+ if (!krbtgt_bytes) {
+ torture_fail(tctx, "(saved test) Could not interpret krbtgt key");
+ }
}
krbsrv_bytes = smbpasswd_gethexpwd(mem_ctx, pac_member_key);
@@ -329,18 +333,23 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
smb_get_krb5_error_message(smb_krb5_context->krb5_context,
ret, mem_ctx)));
- ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
- ENCTYPE_ARCFOUR_HMAC,
- krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
- &krbtgt_keyblock);
- if (ret) {
- krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &server_keyblock);
- torture_fail(tctx,
- talloc_asprintf(tctx,
- "(saved test) Server Keyblock encoding failed: %s",
- smb_get_krb5_error_message(smb_krb5_context->krb5_context,
- ret, mem_ctx)));
+ if (krbtgt_bytes) {
+ ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
+ ENCTYPE_ARCFOUR_HMAC,
+ krbtgt_bytes->hash, sizeof(krbtgt_bytes->hash),
+ &krbtgt_keyblock);
+ if (ret) {
+ krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
+ &server_keyblock);
+ torture_fail(tctx,
+ talloc_asprintf(tctx,
+ "(saved test) Server Keyblock encoding failed: %s",
+ smb_get_krb5_error_message(smb_krb5_context->krb5_context,
+ ret, mem_ctx)));
+ }
+ krbtgt_keyblock_p = &krbtgt_keyblock;
+ } else {
+ krbtgt_keyblock_p = NULL;
}
pac_file = torture_setting_string(tctx, "pac_file", NULL);
@@ -363,7 +372,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
&client_principal);
if (ret) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
torture_fail(tctx,
@@ -379,12 +388,12 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
&pac_data,
tmp_blob,
smb_krb5_context->krb5_context,
- &krbtgt_keyblock,
+ krbtgt_keyblock_p,
&server_keyblock,
client_principal, authtime, NULL);
if (!NT_STATUS_IS_OK(nt_status)) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -400,13 +409,13 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
&logon_info,
tmp_blob,
smb_krb5_context->krb5_context,
- &krbtgt_keyblock,
+ krbtgt_keyblock_p,
&server_keyblock,
client_principal, authtime, NULL);
if (!NT_STATUS_IS_OK(nt_status)) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -424,7 +433,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
&server_info_out);
if (!NT_STATUS_IS_OK(nt_status)) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -440,7 +449,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
"S-1-5-21-3048156945-3961193616-3706469200-1005"),
server_info_out->account_sid)) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -452,17 +461,25 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
dom_sid_string(mem_ctx, server_info_out->account_sid)));
}
+ if (krbtgt_bytes == NULL) {
+ torture_comment(tctx, "skipping PAC encoding tests as non kdc key\n");
+ krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
+ &server_keyblock);
+ krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
+ return true;
+ }
+
ret = kerberos_encode_pac(mem_ctx,
lp_iconv_convenience(tctx->lp_ctx),
pac_data,
smb_krb5_context->krb5_context,
- &krbtgt_keyblock,
+ krbtgt_keyblock_p,
&server_keyblock,
&validate_blob);
if (ret != 0) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -478,7 +495,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
*/
if (tmp_blob.length != validate_blob.length) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -491,7 +508,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -508,14 +525,14 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
lp_iconv_convenience(tctx->lp_ctx),
server_info_out,
smb_krb5_context->krb5_context,
- &krbtgt_keyblock,
+ krbtgt_keyblock_p,
&server_keyblock,
client_principal, authtime,
&validate_blob);
if (ret != 0) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -541,7 +558,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -563,7 +580,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -583,14 +600,14 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
&pac_data,
tmp_blob,
smb_krb5_context->krb5_context,
- &krbtgt_keyblock,
+ krbtgt_keyblock_p,
&server_keyblock,
client_principal,
authtime + 1, NULL);
if (NT_STATUS_IS_OK(nt_status)) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
@@ -608,7 +625,7 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
if (ret) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
torture_fail(tctx, talloc_asprintf(tctx,
@@ -621,13 +638,13 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
&pac_data,
tmp_blob,
smb_krb5_context->krb5_context,
- &krbtgt_keyblock,
+ krbtgt_keyblock_p,
&server_keyblock,
client_principal,
authtime, NULL);
if (NT_STATUS_IS_OK(nt_status)) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on modified principal");
@@ -641,20 +658,20 @@ static bool torture_pac_saved_check(struct torture_context *tctx)
&pac_data,
tmp_blob,
smb_krb5_context->krb5_context,
- &krbtgt_keyblock,
+ krbtgt_keyblock_p,
&server_keyblock,
client_principal,
authtime, NULL);
if (NT_STATUS_IS_OK(nt_status)) {
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
torture_fail(tctx, "(saved test) PAC decoding DID NOT fail on broken checksum");
}
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
- &krbtgt_keyblock);
+ krbtgt_keyblock_p);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
&server_keyblock);
return true;
@@ -666,9 +683,7 @@ struct torture_suite *torture_pac(TALLOC_CTX *mem_ctx)
torture_suite_add_simple_test(suite, "self check",
torture_pac_self_check);
-
torture_suite_add_simple_test(suite, "saved check",
torture_pac_saved_check);
-
return suite;
}
diff --git a/source4/torture/nbt/winsreplication.c b/source4/torture/nbt/winsreplication.c
index ee7a1510d5..6b600bd7cd 100644
--- a/source4/torture/nbt/winsreplication.c
+++ b/source4/torture/nbt/winsreplication.c
@@ -6701,7 +6701,6 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx,
/*
* unique vs. unique section
*/
-#if METZE_NEEDS_TO_LOOK_AT_THIS_ONE
/*
* unique,active vs. unique,active with same ip(s), unchecked
*/
@@ -6728,7 +6727,6 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx,
.apply_expected = true
},
},
-#endif
/*
* unique,active vs. unique,active with different ip(s), positive response
*/
@@ -8967,7 +8965,6 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx,
.sgroup_merge = true
},
},
-#if 0
/*
* sgroup,active vs. sgroup,active with same ip(s)
*/
@@ -9157,7 +9154,6 @@ static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx,
.apply_expected = false
},
},
-#endif
};
if (!ctx->nbtsock_srv) {
@@ -9543,7 +9539,9 @@ static void test_conflict_owned_active_vs_replica_handler_query(struct nbt_name_
talloc_free(rep_packet);
/* make sure we push the reply to the wire */
- event_loop_once(nbtsock->event_ctx);
+ while (nbtsock->send_queue) {
+ event_loop_once(nbtsock->event_ctx);
+ }
msleep(1000);
rec->defend.timeout = 0;
@@ -9598,7 +9596,9 @@ static void test_conflict_owned_active_vs_replica_handler_release(
talloc_free(rep_packet);
/* make sure we push the reply to the wire */
- event_loop_once(nbtsock->event_ctx);
+ while (nbtsock->send_queue) {
+ event_loop_once(nbtsock->event_ctx);
+ }
msleep(1000);
rec->defend.timeout = 0;
diff --git a/source4/torture/raw/open.c b/source4/torture/raw/open.c
index b6979fa0d9..f3494ea3d0 100644
--- a/source4/torture/raw/open.c
+++ b/source4/torture/raw/open.c
@@ -844,6 +844,8 @@ static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context
int fnum = -1;
bool ret = true;
int i;
+ uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
+ uint32_t not_a_directory_mask, unexpected_mask;
struct {
uint32_t open_disp;
bool with_file;
@@ -982,6 +984,10 @@ static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context
}
io.ntcreatex.in.create_options = create_option;
status = smb_raw_open(cli->tree, tctx, &io);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ntcreatex create option 0x%08x gave %s - should give NT_STATUS_OK\n",
+ create_option, nt_errstr(status));
+ }
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
@@ -999,6 +1005,44 @@ static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context
smbcli_close(cli->tree, fnum);
}
+ io.ntcreatex.in.file_attr = 0;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+ io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+
+ /* Check for options that should return NOT_SUPPORTED, OK or INVALID_PARAMETER */
+ ok_mask = 0;
+ not_supported_mask = 0;
+ invalid_parameter_mask = 0;
+ not_a_directory_mask = 0;
+ unexpected_mask = 0;
+ for (i=0; i < 32; i++) {
+ uint32_t create_option = 1<<i;
+ if (create_option & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
+ continue;
+ }
+ io.ntcreatex.in.create_options = create_option;
+ status = smb_raw_open(cli->tree, tctx, &io);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+ not_supported_mask |= create_option;
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
+ ok_mask |= create_option;
+ smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+ invalid_parameter_mask |= create_option;
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
+ not_a_directory_mask |= 1<<i;
+ } else {
+ unexpected_mask |= 1<<i;
+ printf("create option 0x%08x returned %s\n", create_option, nt_errstr(status));
+ }
+ }
+
+ CHECK_VAL(ok_mask, 0x00efcfce);
+ CHECK_VAL(not_a_directory_mask, 0x00000001);
+ CHECK_VAL(not_supported_mask, 0x00002000);
+ CHECK_VAL(invalid_parameter_mask, 0xff100030);
+ CHECK_VAL(unexpected_mask, 0x00000000);
+
smbcli_unlink(cli->tree, fname);
diff --git a/source4/torture/smb2/create.c b/source4/torture/smb2/create.c
index c23ff8b8ce..4d1b4a7ed0 100644
--- a/source4/torture/smb2/create.c
+++ b/source4/torture/smb2/create.c
@@ -52,7 +52,9 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
struct smb2_create io;
NTSTATUS status;
TALLOC_CTX *tmp_ctx = talloc_new(tree);
- uint32_t access_mask, file_attributes, file_attributes_set, denied_mask;
+ uint32_t access_mask, file_attributes_set;
+ uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
+ uint32_t not_a_directory_mask, unexpected_mask;
union smb_fileinfo q;
ZERO_STRUCT(io);
@@ -76,14 +78,6 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
status = smb2_create(tree, tmp_ctx, &io);
CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
- io.in.create_options = 0x00100000;
- status = smb2_create(tree, tmp_ctx, &io);
- CHECK_STATUS(status, NT_STATUS_NOT_SUPPORTED);
-
- io.in.create_options = 0xF0100000;
- status = smb2_create(tree, tmp_ctx, &io);
- CHECK_STATUS(status, NT_STATUS_NOT_SUPPORTED);
-
io.in.create_options = 0;
io.in.file_attributes = FILE_ATTRIBUTE_DEVICE;
@@ -108,6 +102,46 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
status = smb2_create(tree, tmp_ctx, &io);
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+ io.in.file_attributes = 0;
+ io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+ io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+ ok_mask = 0;
+ not_supported_mask = 0;
+ invalid_parameter_mask = 0;
+ not_a_directory_mask = 0;
+ unexpected_mask = 0;
+ {
+ int i;
+ for (i=0;i<32;i++) {
+ io.in.create_options = 1<<i;
+ if (io.in.create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
+ continue;
+ }
+ status = smb2_create(tree, tmp_ctx, &io);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+ not_supported_mask |= 1<<i;
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+ invalid_parameter_mask |= 1<<i;
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
+ not_a_directory_mask |= 1<<i;
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
+ ok_mask |= 1<<i;
+ status = smb2_util_close(tree, io.out.file.handle);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ } else {
+ unexpected_mask |= 1<<i;
+ printf("create option 0x%08x returned %s\n", 1<<i, nt_errstr(status));
+ }
+ }
+ }
+ io.in.create_options = 0;
+
+ CHECK_EQUAL(ok_mask, 0x00efcf7e);
+ CHECK_EQUAL(not_a_directory_mask, 0x00000001);
+ CHECK_EQUAL(not_supported_mask, 0x00102080);
+ CHECK_EQUAL(invalid_parameter_mask, 0xff000000);
+ CHECK_EQUAL(unexpected_mask, 0x00000000);
+
io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
io.in.file_attributes = 0;
access_mask = 0;
@@ -132,31 +166,58 @@ static bool test_create_gentest(struct torture_context *torture, struct smb2_tre
io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
io.in.file_attributes = 0;
- file_attributes = 0;
+ ok_mask = 0;
+ invalid_parameter_mask = 0;
+ unexpected_mask = 0;
file_attributes_set = 0;
- denied_mask = 0;
{
int i;
for (i=0;i<32;i++) {
io.in.file_attributes = 1<<i;
+ if (io.in.file_attributes & FILE_ATTRIBUTE_ENCRYPTED) {
+ continue;
+ }
smb2_deltree(tree, FNAME);
status = smb2_create(tree, tmp_ctx, &io);
if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
- file_attributes |= io.in.file_attributes;
- } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
- denied_mask |= io.in.file_attributes;
- } else {
- CHECK_STATUS(status, NT_STATUS_OK);
+ invalid_parameter_mask |= 1<<i;
+ } else if (NT_STATUS_IS_OK(status)) {
+ uint32_t expected;
+ ok_mask |= 1<<i;
+
+ expected = (io.in.file_attributes | FILE_ATTRIBUTE_ARCHIVE) & 0x00005127;
+ CHECK_EQUAL(io.out.file_attr, expected);
+ file_attributes_set |= io.out.file_attr;
+
status = smb2_util_close(tree, io.out.file.handle);
CHECK_STATUS(status, NT_STATUS_OK);
- file_attributes_set |= io.out.file_attr;
+ } else {
+ unexpected_mask |= 1<<i;
+ printf("file attribute 0x%08x returned %s\n", 1<<i, nt_errstr(status));
}
}
}
- CHECK_EQUAL(file_attributes, 0xffff8048);
- CHECK_EQUAL(denied_mask, 0x4000);
- CHECK_EQUAL(file_attributes_set, 0x00001127);
+ CHECK_EQUAL(ok_mask, 0x00003fb7);
+ CHECK_EQUAL(invalid_parameter_mask, 0xffff8048);
+ CHECK_EQUAL(unexpected_mask, 0x00000000);
+ CHECK_EQUAL(file_attributes_set, 0x00001127);
+
+ smb2_deltree(tree, FNAME);
+
+ /*
+ * Standalone servers doesn't support encryption
+ */
+ io.in.file_attributes = FILE_ATTRIBUTE_ENCRYPTED;
+ status = smb2_create(tree, tmp_ctx, &io);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ printf("FILE_ATTRIBUTE_ENCRYPTED returned %s\n", nt_errstr(status));
+ } else {
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_EQUAL(io.out.file_attr, (FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_ARCHIVE));
+ status = smb2_util_close(tree, io.out.file.handle);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ }
smb2_deltree(tree, FNAME);