*/
#include "includes.h"
+#include "smb1_utils.h"
#include "system/filesys.h"
#include "lib/util/server_id.h"
#include "printing.h"
return True;
}
-/****************************************************************************
- Special FCB or DOS processing in the case of a sharing violation.
- Try and find a duplicated file handle.
-****************************************************************************/
-
-static NTSTATUS fcb_or_dos_open(struct smb_request *req,
- connection_struct *conn,
- files_struct *fsp_to_dup_into,
- const struct smb_filename *smb_fname,
- struct file_id id,
- uint16_t file_pid,
- uint64_t vuid,
- uint32_t access_mask,
- uint32_t share_access,
- uint32_t create_options)
-{
- files_struct *fsp;
-
- DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
- "file %s.\n", smb_fname_str_dbg(smb_fname)));
-
- for(fsp = file_find_di_first(conn->sconn, id); fsp;
- fsp = file_find_di_next(fsp)) {
-
- DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
- "vuid = %llu, file_pid = %u, private_options = 0x%x "
- "access_mask = 0x%x\n", fsp_str_dbg(fsp),
- fsp->fh->fd, (unsigned long long)fsp->vuid,
- (unsigned int)fsp->file_pid,
- (unsigned int)fsp->fh->private_options,
- (unsigned int)fsp->access_mask ));
-
- if (fsp != fsp_to_dup_into &&
- fsp->fh->fd != -1 &&
- fsp->vuid == vuid &&
- fsp->file_pid == file_pid &&
- (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
- NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
- (fsp->access_mask & FILE_WRITE_DATA) &&
- strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
- strequal(fsp->fsp_name->stream_name,
- smb_fname->stream_name)) {
- DEBUG(10,("fcb_or_dos_open: file match\n"));
- break;
- }
- }
-
- if (!fsp) {
- return NT_STATUS_NOT_FOUND;
- }
-
- /* quite an insane set of semantics ... */
- if (is_executable(smb_fname->base_name) &&
- (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
- DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* We need to duplicate this fsp. */
- return dup_file_fsp(req, fsp, access_mask, share_access,
- create_options, fsp_to_dup_into);
-}
-
static void schedule_defer_open(struct share_mode_lock *lck,
struct file_id id,
struct timeval request_time,
SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
- /* Check if this can be done with the deny_dos and fcb
- * calls. */
- if (private_flags &
- (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
- NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
- if (req == NULL) {
- DEBUG(0, ("DOS open without an SMB "
- "request!\n"));
- TALLOC_FREE(lck);
- fd_close(fsp);
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- /* Use the client requested access mask here,
- * not the one we open with. */
- status = fcb_or_dos_open(req,
- conn,
- fsp,
- smb_fname,
- id,
- req->smbpid,
- req->vuid,
- access_mask,
- share_access,
- create_options);
-
- if (NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(lck);
- if (pinfo) {
- *pinfo = FILE_WAS_OPENED;
- }
- return NT_STATUS_OK;
- }
- }
-
/*
* This next line is a subtlety we need for
* MS-Access. If a file open will fail due to share
#include "libcli/smb/smb_signing.h"
#include "lib/util/sys_rw_data.h"
#include "librpc/gen_ndr/open_files.h"
+#include "smb1_utils.h"
/****************************************************************************
Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
/* We have re-scheduled this call. */
goto out;
}
- reply_openerror(req, status);
- goto out;
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
+ reply_openerror(req, status);
+ goto out;
+ }
+
+ fsp = fcb_or_dos_open(
+ req,
+ smb_fname,
+ access_mask,
+ share_mode,
+ create_options,
+ private_flags);
+ if (fsp == NULL) {
+ reply_openerror(req, status);
+ goto out;
+ }
}
/* Ensure we're pointing at the correct stat struct. */
/* We have re-scheduled this call. */
goto out;
}
- reply_openerror(req, status);
- goto out;
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
+ reply_openerror(req, status);
+ goto out;
+ }
+
+ fsp = fcb_or_dos_open(
+ req,
+ smb_fname,
+ access_mask,
+ share_mode,
+ create_options,
+ private_flags);
+ if (fsp == NULL) {
+ reply_openerror(req, status);
+ goto out;
+ }
+ smb_action = FILE_WAS_OPENED;
}
/* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
--- /dev/null
+/*
+ * Unix SMB/CIFS implementation.
+ * Util functions valid in the SMB1 server
+ *
+ * Copyright (C) Volker Lendecke 2019
+ * Copyright by the authors of the functions moved here eventually
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "smb1_utils.h"
+#include "libcli/security/security.h"
+
+/****************************************************************************
+ Special FCB or DOS processing in the case of a sharing violation.
+ Try and find a duplicated file handle.
+****************************************************************************/
+
+struct files_struct *fcb_or_dos_open(
+ struct smb_request *req,
+ const struct smb_filename *smb_fname,
+ uint32_t access_mask,
+ uint32_t share_access,
+ uint32_t create_options,
+ uint32_t private_flags)
+{
+ struct connection_struct *conn = req->conn;
+ struct file_id id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+ struct files_struct *fsp = NULL, *new_fsp = NULL;
+ NTSTATUS status;
+
+ if ((private_flags &
+ (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
+ NTCREATEX_OPTIONS_PRIVATE_DENY_FCB))
+ == 0) {
+ return NULL;
+ }
+
+ for(fsp = file_find_di_first(conn->sconn, id);
+ fsp != NULL;
+ fsp = file_find_di_next(fsp)) {
+
+ DBG_DEBUG("Checking file %s, fd = %d, vuid = %"PRIu64", "
+ "file_pid = %"PRIu16", "
+ "private_options = 0x%"PRIx32", "
+ "access_mask = 0x%"PRIx32"\n",
+ fsp_str_dbg(fsp),
+ fsp->fh->fd,
+ fsp->vuid,
+ fsp->file_pid,
+ fsp->fh->private_options,
+ fsp->access_mask);
+
+ if (fsp->fh->fd != -1 &&
+ fsp->vuid == req->vuid &&
+ fsp->file_pid == req->smbpid &&
+ (fsp->fh->private_options &
+ (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
+ NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
+ (fsp->access_mask & FILE_WRITE_DATA) &&
+ strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
+ strequal(fsp->fsp_name->stream_name,
+ smb_fname->stream_name)) {
+ DBG_DEBUG("file match\n");
+ break;
+ }
+ }
+
+ if (fsp == NULL) {
+ return NULL;
+ }
+
+ /* quite an insane set of semantics ... */
+ if (is_executable(smb_fname->base_name) &&
+ (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
+ DBG_DEBUG("file fail due to is_executable.\n");
+ return NULL;
+ }
+
+ status = file_new(req, conn, &new_fsp);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_DEBUG("file_new failed: %s\n", nt_errstr(status));
+ return NULL;
+ }
+
+ status = dup_file_fsp(
+ req,
+ fsp,
+ access_mask,
+ share_access,
+ create_options,
+ new_fsp);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_DEBUG("dup_file_fsp failed: %s\n", nt_errstr(status));
+ file_free(req, new_fsp);
+ return NULL;
+ }
+
+ return new_fsp;
+}
--- /dev/null
+/*
+ * Unix SMB/CIFS implementation.
+ * Util functions valid in the SMB1 server
+ *
+ * Copyright (C) Volker Lendecke 2019
+ * Copyright by the authors of the functions moved here eventually
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __SMBD_SMB1_UTILS_H__
+#define __SMBD_SMB1_UTILS_H__
+
+#include "includes.h"
+#include "vfs.h"
+#include "proto.h"
+
+struct files_struct *fcb_or_dos_open(
+ struct smb_request *req,
+ const struct smb_filename *smb_fname,
+ uint32_t access_mask,
+ uint32_t share_access,
+ uint32_t create_options,
+ uint32_t private_flags);
+
+#endif
#include "lib/util_ea.h"
#include "lib/readdir_attr.h"
#include "messages.h"
+#include "smb1_utils.h"
#define DIR_ENTRY_SAFETY_MARGIN 4096
/* We have re-scheduled this call. */
goto out;
}
- reply_openerror(req, status);
- goto out;
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
+ reply_openerror(req, status);
+ goto out;
+ }
+
+ fsp = fcb_or_dos_open(
+ req,
+ smb_fname,
+ access_mask,
+ share_mode,
+ create_options,
+ private_flags);
+ if (fsp == NULL) {
+ reply_openerror(req, status);
+ goto out;
+ }
+ smb_action = FILE_WAS_OPENED;
}
size = get_file_size_stat(&smb_fname->st);
smbd/notify.c
smbd/notify_msg.c
smbd/build_options.c
+ smbd/smb1_utils.c
''' + NOTIFY_SOURCES,
deps='''
talloc