diff --git a/source3/include/smb.h b/source3/include/smb.h index 873657a..4f94c3e 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -247,6 +247,7 @@ struct print_file_data { typedef struct files_struct { struct files_struct *next, *prev; int fnum; + uint64_t fpnum; struct connection_struct *conn; struct fd_handle *fh; unsigned int num_smb_operations; diff --git a/source3/smbd/files.c b/source3/smbd/files.c index bdf85db..3ad1824 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -23,6 +23,18 @@ #include "libcli/security/security.h" #include "util_tdb.h" +static uint64_t generate_fid_persistent() { + static uint64_t fid_base = 0; + + if (fid_base == 0) { + generate_random_buffer((uint8_t *)&fid_base, sizeof(uint64_t)); + } else { + fid_base++; + } + + return fid_base; +} + #define VALID_FNUM(fnum) (((fnum) >= 0) && ((fnum) < real_max_open_files)) #define FILE_HANDLE_OFFSET 0x1000 @@ -108,6 +120,11 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn, fsp->fnum = i + FILE_HANDLE_OFFSET; SMB_ASSERT(fsp->fnum < 65536); + /* For SMB2 correctness you must have a "Globally Unique" + * persistent file id. */ + + fsp->fpnum = generate_fid_persistent(); + /* * Create an smb_filename with "" for the base_name. There are very * few NULL checks, so make sure it's initialized with something. to diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c index ce583ac..181447b 100644 --- a/source3/smbd/smb2_break.c +++ b/source3/smbd/smb2_break.c @@ -62,12 +62,6 @@ NTSTATUS smbd_smb2_request_process_break(struct smbd_smb2_request *req) in_file_id_persistent = BVAL(inbody, 0x08); in_file_id_volatile = BVAL(inbody, 0x10); - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - subreq = smbd_smb2_oplock_break_send(req, req->sconn->smb2.event_ctx, req, @@ -264,7 +258,7 @@ void send_break_message_smb2(files_struct *fsp, int level) (unsigned int)smb2_oplock_level )); status = smbd_smb2_send_oplock_break(fsp->conn->sconn, - (uint64_t)fsp->fnum, + (uint64_t)fsp->fpnum, (uint64_t)fsp->fnum, smb2_oplock_level); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index ffe08cc..c0d8ac1 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -54,12 +54,6 @@ NTSTATUS smbd_smb2_request_process_close(struct smbd_smb2_request *req) in_file_id_persistent = BVAL(inbody, 0x08); in_file_id_volatile = BVAL(inbody, 0x10); - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - status = smbd_smb2_close(req, in_flags, in_file_id_volatile, diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index a98422c..ae031f7 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -827,7 +827,12 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, if (state->out_file_attributes == 0) { state->out_file_attributes = FILE_ATTRIBUTE_NORMAL; } - state->out_file_id_persistent = result->fnum; + + /* Note the file_id_persistent must be "Globally Unique." per + * [MS-SMB2]. -ira + */ + + state->out_file_id_persistent = result->fpnum; state->out_file_id_volatile = result->fnum; state->out_context_blobs = out_context_blobs; diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c index 3dcc768..fe09d79 100644 --- a/source3/smbd/smb2_find.c +++ b/source3/smbd/smb2_find.c @@ -115,12 +115,6 @@ NTSTATUS smbd_smb2_request_process_find(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_OBJECT_NAME_INVALID); } - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - subreq = smbd_smb2_find_send(req, req->sconn->smb2.event_ctx, req, diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c index 5f3c42a..59f0b50 100644 --- a/source3/smbd/smb2_flush.c +++ b/source3/smbd/smb2_flush.c @@ -49,12 +49,6 @@ NTSTATUS smbd_smb2_request_process_flush(struct smbd_smb2_request *req) in_file_id_persistent = BVAL(inbody, 0x08); in_file_id_volatile = BVAL(inbody, 0x10); - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - subreq = smbd_smb2_flush_send(req, req->sconn->smb2.event_ctx, req, diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index c5d2d62..a8e8586 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -97,12 +97,6 @@ NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - subreq = smbd_smb2_getinfo_send(req, req->sconn->smb2.event_ctx, req, diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c index 17b9154..78a8b48 100644 --- a/source3/smbd/smb2_ioctl.c +++ b/source3/smbd/smb2_ioctl.c @@ -88,15 +88,6 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req) in_input_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base; in_input_buffer.length = in_input_length; - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent == UINT64_MAX && - in_file_id_volatile == UINT64_MAX) { - /* without a handle */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - subreq = smbd_smb2_ioctl_send(req, req->sconn->smb2.event_ctx, req, diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 28612ae..29a2cb8 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -90,12 +90,6 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - in_locks = talloc_array(req, struct smbd_smb2_lock_element, in_lock_count); if (in_locks == NULL) { diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c index 49c6a54..f48fef9 100644 --- a/source3/smbd/smb2_notify.c +++ b/source3/smbd/smb2_notify.c @@ -77,12 +77,6 @@ NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - subreq = smbd_smb2_notify_send(req, req->sconn->smb2.event_ctx, req, diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c index 21082e6..85a9910 100644 --- a/source3/smbd/smb2_read.c +++ b/source3/smbd/smb2_read.c @@ -80,12 +80,6 @@ NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - subreq = smbd_smb2_read_send(req, req->sconn->smb2.event_ctx, req, diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c index 751190a..5c426fa 100644 --- a/source3/smbd/smb2_setinfo.c +++ b/source3/smbd/smb2_setinfo.c @@ -85,12 +85,6 @@ NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - subreq = smbd_smb2_setinfo_send(req, req->sconn->smb2.event_ctx, req, diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c index b2360ca..e566a20 100644 --- a/source3/smbd/smb2_write.c +++ b/source3/smbd/smb2_write.c @@ -88,12 +88,6 @@ NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req) in_data_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base; in_data_buffer.length = in_data_length; - if (req->compat_chain_fsp) { - /* skip check */ - } else if (in_file_id_persistent != in_file_id_volatile) { - return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); - } - subreq = smbd_smb2_write_send(req, req->sconn->smb2.event_ctx, req,