int requested_oplock_level;
struct smb2_create_blob *dhnc = NULL;
struct smb2_create_blob *dh2c = NULL;
+ struct smb2_create_blob *dhnq = NULL;
+ struct smb2_create_blob *dh2q = NULL;
struct smbXsrv_open *op = NULL;
ZERO_STRUCT(out_context_blobs);
in_name ));
}
+ dhnq = smb2_create_blob_find(&in_context_blobs,
+ SMB2_CREATE_TAG_DHNQ);
dhnc = smb2_create_blob_find(&in_context_blobs,
SMB2_CREATE_TAG_DHNC);
+ dh2q = smb2_create_blob_find(&in_context_blobs,
+ SMB2_CREATE_TAG_DH2Q);
+ dh2c = smb2_create_blob_find(&in_context_blobs,
+ SMB2_CREATE_TAG_DH2C);
+
+ if ((dhnc && dh2c) || (dhnc && dh2q) || (dh2c && dhnq) ||
+ (dh2q && dh2c))
+ {
+ /* not both are allowed at the same time */
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
if (dhnc) {
if (dhnc->data.length != 16) {
if (in_context_blobs.num_blobs != 1) {
/*
* DHNC should be the only one.
+ * TODO: This is only true for the oplock case!
+ * For leases, lease request is required additionally!
*/
tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
return tevent_req_post(req, ev);
}
}
- dh2c = smb2_create_blob_find(&in_context_blobs,
- SMB2_CREATE_TAG_DH2C);
if (dh2c) {
if (dh2c->data.length != 36) {
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
if (in_context_blobs.num_blobs != 1) {
/*
* DH2C should be the only one.
+ * TODO: This is only true for the oplock case!
+ * For leases, lease request is required additionally!
*/
tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
return tevent_req_post(req, ev);
NTTIME max_access_time = 0;
struct smb2_create_blob *secd = NULL;
struct security_descriptor *sec_desc = NULL;
- struct smb2_create_blob *dhnq = NULL;
struct smb2_create_blob *alsi = NULL;
uint64_t allocation_size = 0;
struct smb2_create_blob *twrp = NULL;
struct smb2_create_blob *qfid = NULL;
- struct GUID create_guid = GUID_zero();
+ struct GUID _create_guid = GUID_zero();
+ struct GUID *create_guid = NULL;
bool update_open = false;
bool durable_requested = false;
uint32_t durable_timeout_msec = 0;
bool do_durable_reconnect = false;
- struct smb2_create_blob *dh2q = NULL;
+ uint64_t persistent_id = 0;
exta = smb2_create_blob_find(&in_context_blobs,
SMB2_CREATE_TAG_EXTA);
SMB2_CREATE_TAG_MXAC);
secd = smb2_create_blob_find(&in_context_blobs,
SMB2_CREATE_TAG_SECD);
- dhnq = smb2_create_blob_find(&in_context_blobs,
- SMB2_CREATE_TAG_DHNQ);
alsi = smb2_create_blob_find(&in_context_blobs,
SMB2_CREATE_TAG_ALSI);
twrp = smb2_create_blob_find(&in_context_blobs,
SMB2_CREATE_TAG_TWRP);
qfid = smb2_create_blob_find(&in_context_blobs,
SMB2_CREATE_TAG_QFID);
- dh2q = smb2_create_blob_find(&in_context_blobs,
- SMB2_CREATE_TAG_DH2Q);
fname = talloc_strdup(state, in_name);
if (tevent_req_nomem(fname, req)) {
tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
return tevent_req_post(req, ev);
}
+
+ if (ea_list_has_invalid_name(ea_list)) {
+ tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
+ return tevent_req_post(req, ev);
+ }
}
if (mxac) {
create_guid_blob = data_blob_const(p + 16, 16);
status = GUID_from_ndr_blob(&create_guid_blob,
- &create_guid);
+ &_create_guid);
if (tevent_req_nterror(req, status)) {
return tevent_req_post(req, ev);
}
+ create_guid = &_create_guid;
/*
* we need to store the create_guid later
*/
}
if (dhnc) {
- NTTIME now = timeval_to_nttime(&smb2req->request_time);
- uint64_t persistent_id;
-
persistent_id = BVAL(dhnc->data.data, 0);
- status = smb2srv_open_recreate(smb2req->sconn->conn,
- smb1req->conn->session_info,
- persistent_id, create_guid,
- now, &op);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("smbd_smb2_create_send: "
- "smb2srv_open_recreate v1 failed: %s\n",
- nt_errstr(status)));
- tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
- }
-
- DEBUG(10, ("smb2_create_send: DHNC: %s recreate the "
- "smb2srv_open struct for a durable handle.\n",
- op->global->durable ? "did" : "could not"));
-
- if (!op->global->durable) {
- talloc_free(op);
- tevent_req_nterror(req,
- NT_STATUS_OBJECT_NAME_NOT_FOUND);
- return tevent_req_post(req, ev);
- }
-
do_durable_reconnect = true;
}
if (dh2c) {
const uint8_t *p = dh2c->data.data;
- NTTIME now = timeval_to_nttime(&smb2req->request_time);
- uint64_t persistent_id;
DATA_BLOB create_guid_blob;
persistent_id = BVAL(p, 0);
create_guid_blob = data_blob_const(p + 16, 16);
status = GUID_from_ndr_blob(&create_guid_blob,
- &create_guid);
+ &_create_guid);
if (tevent_req_nterror(req, status)) {
return tevent_req_post(req, ev);
}
-
- status = smb2srv_open_recreate(smb2req->sconn->conn,
- smb1req->conn->session_info,
- persistent_id, create_guid,
- now, &op);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("smbd_smb2_create_send: "
- "smb2srv_open_recreate v2 failed: %s\n",
- nt_errstr(status)));
- tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
- }
-
- DEBUG(10, ("smb2_create_send: DH2C: %s recreate the "
- "smb2srv_open struct for a durable handle.\n",
- op->global->durable ? "did" : "could not"));
-
- if (!op->global->durable) {
- talloc_free(op);
- tevent_req_nterror(req,
- NT_STATUS_OBJECT_NAME_NOT_FOUND);
- return tevent_req_post(req, ev);
- }
+ create_guid = &_create_guid;
do_durable_reconnect = true;
}
*/
if (do_durable_reconnect) {
DATA_BLOB new_cookie = data_blob_null;
+ NTTIME now = timeval_to_nttime(&smb2req->request_time);
+
+ status = smb2srv_open_recreate(smb2req->sconn->conn,
+ smb1req->conn->session_info,
+ persistent_id, create_guid,
+ now, &op);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("smbd_smb2_create_send: "
+ "smb2srv_open_recreate failed: %s\n",
+ nt_errstr(status)));
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+
+ DEBUG(10, ("smb2_create_send: %s to recreate the "
+ "smb2srv_open struct for a durable handle.\n",
+ op->global->durable ? "succeded" : "failed"));
+
+ if (!op->global->durable) {
+ talloc_free(op);
+ tevent_req_nterror(req,
+ NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return tevent_req_post(req, ev);
+ }
status = SMB_VFS_DURABLE_RECONNECT(smb1req->conn,
smb1req,
- op,
+ op, /* smbXsrv_open input */
op->global->backend_cookie,
- op, &result, &new_cookie);
+ op, /* TALLOC_CTX */
+ &result, &new_cookie);
if (!NT_STATUS_IS_OK(status)) {
NTSTATUS return_status;
op->status = NT_STATUS_OK;
op->global->disconnect_time = 0;
- status = smbXsrv_open_update(op);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
- }
+ /* save the timout for later update */
+ durable_timeout_msec = op->global->durable_timeout_msec;
+
+ update_open = true;
info = FILE_WAS_OPENED;
} else {
smb1req->conn,
smb1req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- 0, /* unix_convert flags */
+ (in_create_disposition == FILE_CREATE) ?
+ UCF_CREATING_FILE : 0,
NULL, /* ppath_contains_wcards */
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
}
if (update_open) {
- op->global->create_guid = create_guid;
+ op->global->create_guid = _create_guid;
status = smbXsrv_open_update(op);
DEBUG(10, ("smb2_create_send: smbXsrv_open_update "
return true;
}
-/*********************************************************
- Re-process this call.
-*********************************************************/
-
-static void smb2_deferred_open_timer(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval _tval,
- void *private_data)
-{
- NTSTATUS status;
- struct smbd_smb2_create_state *state = NULL;
- struct smbd_smb2_request *smb2req = talloc_get_type(private_data,
- struct smbd_smb2_request);
-
- DEBUG(10,("smb2_deferred_open_timer: [idx=%d], %s\n",
- smb2req->current_idx,
- tevent_req_default_print(smb2req->subreq, talloc_tos()) ));
-
- state = tevent_req_data(smb2req->subreq,
- struct smbd_smb2_create_state);
- if (!state) {
- return;
- }
- /*
- * Null this out, don't talloc_free. It will
- * be talloc_free'd by the tevent library when
- * this returns.
- */
- state->te = NULL;
- /* Ensure we don't have any outstanding immediate event. */
- TALLOC_FREE(state->im);
-
- /*
- * This is subtle. We must null out the callback
- * before rescheduling, else the first call to
- * tevent_req_nterror() causes the _receive()
- * function to be called, this causing tevent_req_post()
- * to crash.
- */
- tevent_req_set_callback(smb2req->subreq, NULL, NULL);
-
- status = smbd_smb2_request_dispatch(smb2req);
-
- if (!NT_STATUS_IS_OK(status)) {
- smbd_server_connection_terminate(smb2req->sconn,
- nt_errstr(status));
- }
-}
-
static bool smbd_smb2_create_cancel(struct tevent_req *req)
{
struct smbd_smb2_request *smb2req = NULL;
return false;
}
- remove_deferred_open_entry(state->id, mid,
- messaging_server_id(smb2req->sconn->msg_ctx));
remove_deferred_open_message_smb2_internal(smb2req, mid);
tevent_req_defer_callback(req, smb2req->sconn->ev_ctx);
true) ));
state->open_was_deferred = true;
- state->te = tevent_add_timer(smb2req->sconn->ev_ctx,
- state,
- end_time,
- smb2_deferred_open_timer,
- smb2req);
- if (!state->te) {
- return false;
- }
/* allow this request to be canceled */
tevent_req_set_cancel_fn(req, smbd_smb2_create_cancel);