The branch, master has been updated
via ef3f44a1de1 ci: Don't run on private rackspace runner
via fccdc1be993 smbd: Change open_rootdir_pathref_fsp() to return a
smb_filename
via f0543b2b596 smbd: Factor out openat_pathref_fsp_simple_openat()
via 84dd7fe6f03 smbd: Fix a comment
via bcda7f636e0 smbd: Make fsp_set_gen_id() static
via f150382db3b smbd: Make fsp_new() return a files_struct
via 1e9dc025613 smbd: Make fsp_set_smb_fname() return bool
via 621edbce3c9 smbd: Make fsp_attach_smb_fname() return bool
via d7fb7813d43 smbd: Make fsp_smb_fname_link() return bool
via 03aea18ac66 smbd: Make file_name_hash() return bool
from b6c1d0e5cee printing: Fix coverity issue CID#1669074 (Unchecked
return value)
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit ef3f44a1de153fdd1aa719a4ecba35d9b11e0756
Author: Volker Lendecke <[email protected]>
Date: Sun Nov 16 15:53:19 2025 +0100
ci: Don't run on private rackspace runner
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
Autobuild-User(master): Volker Lendecke <[email protected]>
Autobuild-Date(master): Mon Nov 17 09:37:30 UTC 2025 on atb-devel-224
commit fccdc1be9933f7768b7ded582970d3c26350cf29
Author: Volker Lendecke <[email protected]>
Date: Wed Sep 10 18:12:22 2025 +0200
smbd: Change open_rootdir_pathref_fsp() to return a smb_filename
Simpler and safer to close in the caller, and
openat_pathref_fsp_rootdir() can use
openat_pathref_fsp_simple_openat(). De-duplicate some logic.
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
commit f0543b2b5960900f3746c360680ec635a6dba875
Author: Volker Lendecke <[email protected]>
Date: Wed Sep 10 18:03:39 2025 +0200
smbd: Factor out openat_pathref_fsp_simple_openat()
open_rootdir_pathref_fsp() and openat_pathref_fsp_dot() serve very
similar purposes. Avoid code duplication, this is to be used in
open_rootdir_pathref_fsp() next.
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
commit 84dd7fe6f0312d0d6d505e9bf6c19c9bfae6b417
Author: Volker Lendecke <[email protected]>
Date: Fri Oct 10 15:51:14 2025 +0200
smbd: Fix a comment
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
commit bcda7f636e036109ef80adeb5c78934e73913976
Author: Volker Lendecke <[email protected]>
Date: Fri Oct 10 15:50:56 2025 +0200
smbd: Make fsp_set_gen_id() static
Only called from files.c
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
commit f150382db3bcb3cdcc222efac2691fa1a0fef1c2
Author: Volker Lendecke <[email protected]>
Date: Thu Oct 23 20:11:35 2025 +0200
smbd: Make fsp_new() return a files_struct
There's only the ENOMEM failure condition
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
commit 1e9dc025613d99e0f9922c621e07484838ace810
Author: Volker Lendecke <[email protected]>
Date: Thu Oct 23 20:00:08 2025 +0200
smbd: Make fsp_set_smb_fname() return bool
There's only the ENOMEM failure condition
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
commit 621edbce3c986b786e3347b4ebd51323eed2e2d7
Author: Volker Lendecke <[email protected]>
Date: Thu Oct 23 19:47:09 2025 +0200
smbd: Make fsp_attach_smb_fname() return bool
There's only the ENOMEM failure condition
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
commit d7fb7813d43017a6376cf500ca2685b2780ef7cc
Author: Volker Lendecke <[email protected]>
Date: Thu Oct 23 19:38:16 2025 +0200
smbd: Make fsp_smb_fname_link() return bool
There's only the ENOMEM failure condition
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
commit 03aea18ac667131efbdfe49792ed63992822ef76
Author: Volker Lendecke <[email protected]>
Date: Thu Oct 23 19:27:13 2025 +0200
smbd: Make file_name_hash() return bool
There's only the ENOMEM failure condition
Signed-off-by: Volker Lendecke <[email protected]>
Reviewed-by: Ralph Boehme <[email protected]>
-----------------------------------------------------------------------
Summary of changes:
.gitlab-ci-main.yml | 2 +-
source3/modules/vfs_fake_acls.c | 14 +-
source3/smbd/durable.c | 19 +-
source3/smbd/fake_file.c | 5 +-
source3/smbd/files.c | 471 +++++++++++++++++++---------------------
source3/smbd/open.c | 44 ++--
source3/smbd/proto.h | 14 +-
source3/smbd/smb1_utils.c | 7 +-
source3/smbd/smb2_pipes.c | 8 +-
source3/smbd/smb2_reply.c | 7 +-
10 files changed, 288 insertions(+), 303 deletions(-)
Changeset truncated at 500 lines:
diff --git a/.gitlab-ci-main.yml b/.gitlab-ci-main.yml
index 86a5361dd27..9934d005e81 100644
--- a/.gitlab-ci-main.yml
+++ b/.gitlab-ci-main.yml
@@ -486,7 +486,7 @@ samba-fileserver:
extends: .needs_samba-h5l-build-ext4
samba-fileserver-without-smb1:
- extends: .needs_samba-without-smb1-build-5_15
+ extends: .needs_samba-without-smb1-build
# This is a full build without the AD DC so we test the build with MIT
# Kerberos from the default system (Ubuntu 22.04 at this stage).
diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c
index 9c12af42d50..79328da74d9 100644
--- a/source3/modules/vfs_fake_acls.c
+++ b/source3/modules/vfs_fake_acls.c
@@ -100,7 +100,7 @@ static int fake_acls_fstatat(struct vfs_handle_struct
*handle,
connection_struct *conn = handle->conn;
int ret = -1;
struct in_pathref_data *prd = NULL;
- struct files_struct *root_fsp = NULL;
+ struct smb_filename *rootdir = NULL;
struct files_struct *new_dirfsp = NULL;
struct smb_filename *smb_fname = NULL;
struct smb_filename *new_relname = NULL;
@@ -150,13 +150,15 @@ static int fake_acls_fstatat(struct vfs_handle_struct
*handle,
* paths, make this relative to "/"
*/
base_name += 1;
- status = open_rootdir_pathref_fsp(conn, &root_fsp);
+ status = openat_pathref_fsp_rootdir(talloc_tos(),
+ conn,
+ &rootdir);
if (!NT_STATUS_IS_OK(status)) {
prd->calling_pathref_fsp = false;
errno = ENOENT;
return -1;
}
- dirfsp = root_fsp;
+ dirfsp = rootdir->fsp;
}
if (ISDOT(base_name)) {
@@ -212,11 +214,7 @@ static int fake_acls_fstatat(struct vfs_handle_struct
*handle,
&sbuf->st_ex_uid,
&sbuf->st_ex_gid);
- if (root_fsp != NULL) {
- fd_close(root_fsp);
- file_free(NULL, root_fsp);
- root_fsp = NULL;
- }
+ TALLOC_FREE(rootdir);
fd_close(new_dirfsp);
file_free(NULL, new_dirfsp);
new_dirfsp = NULL;
diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c
index 57416e506eb..fe6dd00b64a 100644
--- a/source3/smbd/durable.c
+++ b/source3/smbd/durable.c
@@ -801,6 +801,7 @@ NTSTATUS vfs_default_durable_reconnect(struct
connection_struct *conn,
struct file_id file_id;
NTSTATUS status;
enum ndr_err_code ndr_err;
+ bool ok;
*result = NULL;
*new_cookie = data_blob_null;
@@ -877,11 +878,10 @@ NTSTATUS vfs_default_durable_reconnect(struct
connection_struct *conn,
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- status = fsp_new(conn, conn, &state.fsp);
- if (!NT_STATUS_IS_OK(status)) {
- DBG_ERR("failed to create new fsp: %s\n",
- nt_errstr(status));
- return status;
+ state.fsp = fsp_new(conn, conn);
+ if (state.fsp == NULL) {
+ DBG_ERR("failed to create new fsp\n");
+ return NT_STATUS_NO_MEMORY;
}
state.fsp->file_id = file_id;
state.fsp->file_pid = smb1req->smbpid;
@@ -889,12 +889,11 @@ NTSTATUS vfs_default_durable_reconnect(struct
connection_struct *conn,
state.fsp->fnum = op->local_id;
fh_set_gen_id(state.fsp->fh, op->global->open_global_id);
- status = fsp_set_smb_fname(state.fsp, smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- DBG_ERR("fsp_set_smb_fname failed: %s\n",
- nt_errstr(status));
+ ok = fsp_set_smb_fname(state.fsp, smb_fname);
+ if (!ok) {
+ DBG_ERR("fsp_set_smb_fname failed\n");
file_free(smb1req, state.fsp);
- return status;
+ return NT_STATUS_NO_MEMORY;
}
/*
diff --git a/source3/smbd/fake_file.c b/source3/smbd/fake_file.c
index 32f2595191f..7e561814769 100644
--- a/source3/smbd/fake_file.c
+++ b/source3/smbd/fake_file.c
@@ -145,6 +145,7 @@ NTSTATUS open_fake_file(struct smb_request *req,
connection_struct *conn,
loadparm_s3_global_substitution();
files_struct *fsp = NULL;
NTSTATUS status;
+ bool ok;
/* access check */
if (geteuid() != sec_initial_uid()) {
@@ -172,8 +173,8 @@ NTSTATUS open_fake_file(struct smb_request *req,
connection_struct *conn,
fh_set_pos(fsp->fh, -1);
fsp->fsp_flags.can_lock = false; /* Should this be true ? - No, JRA */
fsp->access_mask = access_mask;
- status = fsp_set_smb_fname(fsp, smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
+ ok = fsp_set_smb_fname(fsp, smb_fname);
+ if (!ok) {
file_free(req, fsp);
return NT_STATUS_NO_MEMORY;
}
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 209c7fcf2b4..33366102774 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -30,16 +30,15 @@
#define FILE_HANDLE_OFFSET 0x1000
-static NTSTATUS fsp_attach_smb_fname(struct files_struct *fsp,
- struct smb_filename **_smb_fname);
+static bool fsp_attach_smb_fname(struct files_struct *fsp,
+ struct smb_filename **_smb_fname);
/**
* create new fsp to be used for file_new or a durable handle reconnect
*/
-NTSTATUS fsp_new(struct connection_struct *conn, TALLOC_CTX *mem_ctx,
- files_struct **result)
+struct files_struct *fsp_new(TALLOC_CTX *mem_ctx,
+ struct connection_struct *conn)
{
- NTSTATUS status = NT_STATUS_NO_MEMORY;
files_struct *fsp = NULL;
struct smbd_server_connection *sconn = conn->sconn;
@@ -78,8 +77,7 @@ NTSTATUS fsp_new(struct connection_struct *conn, TALLOC_CTX
*mem_ctx,
DBG_INFO("allocated files structure (%u used)\n",
(unsigned int)sconn->num_files);
- *result = fsp;
- return NT_STATUS_OK;
+ return fsp;
fail:
if (fsp != NULL) {
@@ -87,16 +85,18 @@ fail:
}
TALLOC_FREE(fsp);
- return status;
+ return NULL;
}
-void fsp_set_gen_id(files_struct *fsp)
+static void fsp_set_gen_id(files_struct *fsp)
{
static uint64_t gen_id = UINT32_MAX;
/*
- * These ids are only used for internal opens, which gives us 4 billion
- * opens until we wrap.
+ * We use the space above UINT32_MAX for internal opens so
+ * that we don't conflict with real opens. Real opens use the
+ * persistent part of the file handle, which is cut to 32-bits
+ * to be used as an index in srvsvc calls.
*/
gen_id++;
if (gen_id == 0) {
@@ -152,9 +152,9 @@ NTSTATUS file_new(struct smb_request *req,
connection_struct *conn,
files_struct *fsp;
NTSTATUS status;
- status = fsp_new(conn, conn, &fsp);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ fsp = fsp_new(conn, conn);
+ if (fsp == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
GetTimeOfDay(&fsp->open_time);
@@ -195,16 +195,17 @@ NTSTATUS create_internal_fsp(connection_struct *conn,
{
struct files_struct *fsp = NULL;
NTSTATUS status;
+ bool ok;
status = file_new(NULL, conn, &fsp);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- status = fsp_set_smb_fname(fsp, smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
+ ok = fsp_set_smb_fname(fsp, smb_fname);
+ if (!ok) {
file_free(NULL, fsp);
- return status;
+ return NT_STATUS_NO_MEMORY;
}
*_fsp = fsp;
@@ -316,9 +317,9 @@ static int fsp_smb_fname_link_destructor(struct
fsp_smb_fname_link *link)
return 0;
}
-static NTSTATUS fsp_smb_fname_link(struct files_struct *fsp,
- struct fsp_smb_fname_link **smb_fname_link,
- struct files_struct **smb_fname_fsp)
+static bool fsp_smb_fname_link(struct files_struct *fsp,
+ struct fsp_smb_fname_link **smb_fname_link,
+ struct files_struct **smb_fname_fsp)
{
struct fsp_smb_fname_link *link = NULL;
@@ -327,7 +328,7 @@ static NTSTATUS fsp_smb_fname_link(struct files_struct *fsp,
link = talloc_zero(fsp, struct fsp_smb_fname_link);
if (link == NULL) {
- return NT_STATUS_NO_MEMORY;
+ return false;
}
link->smb_fname_link = smb_fname_link;
@@ -336,7 +337,7 @@ static NTSTATUS fsp_smb_fname_link(struct files_struct *fsp,
*smb_fname_fsp = fsp;
talloc_set_destructor(link, fsp_smb_fname_link_destructor);
- return NT_STATUS_OK;
+ return true;
}
/*
@@ -409,14 +410,15 @@ static NTSTATUS openat_pathref_fullname(
{
struct files_struct *fsp = NULL;
NTSTATUS status;
+ bool ok;
DBG_DEBUG("smb_fname [%s]\n", smb_fname_str_dbg(smb_fname));
SMB_ASSERT(smb_fname->fsp == NULL);
- status = fsp_new(conn, conn, &fsp);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ fsp = fsp_new(conn, conn);
+ if (fsp == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
GetTimeOfDay(&fsp->open_time);
@@ -424,9 +426,9 @@ static NTSTATUS openat_pathref_fullname(
fsp->fsp_flags.is_pathref = true;
- status = fsp_attach_smb_fname(fsp, full_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
+ ok = fsp_attach_smb_fname(fsp, full_fname);
+ if (!ok) {
+ goto nomem;
}
status = fd_openat(dirfsp, smb_fname, fsp, how);
@@ -469,11 +471,9 @@ static NTSTATUS openat_pathref_fullname(
fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
- status = fsp_smb_fname_link(fsp,
- &smb_fname->fsp_link,
- &smb_fname->fsp);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
+ ok = fsp_smb_fname_link(fsp, &smb_fname->fsp_link, &smb_fname->fsp);
+ if (!ok) {
+ goto nomem;
}
DBG_DEBUG("fsp [%s]: OK\n", fsp_str_dbg(fsp));
@@ -481,6 +481,8 @@ static NTSTATUS openat_pathref_fullname(
talloc_set_destructor(smb_fname, smb_fname_fsp_destructor);
return NT_STATUS_OK;
+nomem:
+ status = NT_STATUS_NO_MEMORY;
fail:
DBG_DEBUG("Opening pathref for [%s] failed: %s\n",
smb_fname_str_dbg(smb_fname),
@@ -582,59 +584,131 @@ fail:
return status;
}
-NTSTATUS open_rootdir_pathref_fsp(connection_struct *conn,
- struct files_struct **_fsp)
+static NTSTATUS openat_pathref_fsp_simple_openat(TALLOC_CTX *mem_ctx,
+ struct files_struct *dirfsp,
+ const char *name,
+ uint32_t flags,
+ struct smb_filename **_fname)
{
- struct smb_filename slash = { .base_name = discard_const_p(char, "/") };
- struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
+ struct connection_struct *conn = dirfsp->conn;
+ struct smb_filename *fname = NULL;
struct files_struct *fsp = NULL;
+ struct smb_filename *full_fname = NULL;
+ struct vfs_open_how how = {.flags = O_NOFOLLOW};
NTSTATUS status;
int fd;
+ bool ok;
- status = fsp_new(conn, conn, &fsp);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
+#ifdef O_DIRECTORY
+ how.flags |= O_DIRECTORY;
+#endif
+
+#ifdef O_PATH
+ how.flags |= O_PATH;
+#else
+ how.flags |= (O_RDONLY | O_NONBLOCK);
+#endif
+
+ fname = synthetic_smb_fname(mem_ctx, name, NULL, NULL, 0, flags);
+ if (fname == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ fsp = fsp_new(conn, conn);
+ if (fsp == NULL) {
+ DBG_DEBUG("fsp_new() failed\n");
+ return NT_STATUS_NO_MEMORY;
}
+
GetTimeOfDay(&fsp->open_time);
ZERO_STRUCT(conn->sconn->fsp_fi_cache);
+
fsp->fsp_flags.is_pathref = true;
- status = fsp_set_smb_fname(fsp, &slash);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
+ full_fname = full_path_from_dirfsp_atname(conn, dirfsp, fname);
+ if (full_fname == NULL) {
+ DBG_DEBUG("full_path_from_dirfsp_atname(%s/%s) failed\n",
+ fsp_str_dbg(dirfsp),
+ fname->base_name);
+ file_free(NULL, fsp);
+ TALLOC_FREE(fname);
+ return NT_STATUS_NO_MEMORY;
}
- fd = SMB_VFS_OPENAT(conn,
- conn->cwd_fsp,
- fsp->fsp_name,
- fsp,
- &how);
+ ok = fsp_attach_smb_fname(fsp, &full_fname);
+ if (!ok) {
+ DBG_DEBUG("fsp_attach_smb_fname(fsp, %s) failed\n",
+ smb_fname_str_dbg(full_fname));
+ file_free(NULL, fsp);
+ TALLOC_FREE(fname);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ fd = SMB_VFS_OPENAT(conn, dirfsp, fname, fsp, &how);
if (fd == -1) {
status = map_nt_error_from_unix(errno);
- goto fail;
+ DBG_DEBUG("smb_vfs_openat(%s/%s) failed: %s\n",
+ fsp_str_dbg(dirfsp),
+ fname->base_name,
+ strerror(errno));
+ file_free(NULL, fsp);
+ TALLOC_FREE(fname);
+ return status;
}
+
fsp_set_fd(fsp, fd);
status = vfs_stat_fsp(fsp);
+
if (!NT_STATUS_IS_OK(status)) {
- DBG_DEBUG("vfs_stat_fsp(\"/\") failed: %s\n",
nt_errstr(status));
- goto close_fail;
+ DBG_DEBUG("vfs_stat_fsp(\"/\") failed: %s\n",
+ nt_errstr(status));
+ fd_close(fsp);
+ file_free(NULL, fsp);
+ TALLOC_FREE(fname);
+ return status;
}
+
fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
- if (!fsp->fsp_flags.is_directory) {
- DBG_DEBUG("\"/\" not a directory\n");
- status = NT_STATUS_UNEXPECTED_IO_ERROR;
- goto close_fail;
- }
+ fsp->fsp_flags.posix_open = ((fname->flags & SMB_FILENAME_POSIX_PATH) !=
+ 0);
fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
- *_fsp = fsp;
+
+ fname->st = fsp->fsp_name->st;
+
+ ok = fsp_smb_fname_link(fsp, &fname->fsp_link, &fname->fsp);
+ if (!ok) {
+ DBG_DEBUG("fsp_smb_fname_link() failed\n");
+ fd_close(fsp);
+ file_free(NULL, fsp);
+ TALLOC_FREE(fname);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ DBG_DEBUG("fsp [%s]: OK, fd=%d\n", fsp_str_dbg(fsp), fd);
+
+ talloc_set_destructor(fname, smb_fname_fsp_destructor);
+
+ *_fname = fname;
+
return NT_STATUS_OK;
+}
-close_fail:
- fd_close(fsp);
-fail:
- file_free(NULL, fsp);
- return status;
+NTSTATUS openat_pathref_fsp_rootdir(TALLOC_CTX *mem_ctx,
+ struct connection_struct *conn,
+ struct smb_filename **_root)
+{
+ struct smb_filename *root = NULL;
+ NTSTATUS status;
+
+ status = openat_pathref_fsp_simple_openat(
+ mem_ctx, conn->cwd_fsp, "/", 0, &root);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ *_root = root;
+ return NT_STATUS_OK;
}
/*
@@ -654,6 +728,7 @@ NTSTATUS open_stream_pathref_fsp(
struct vfs_open_how how = { .flags = O_RDONLY|O_NONBLOCK, };
NTSTATUS status;
int fd;
+ bool ok;
SMB_ASSERT(smb_fname->fsp == NULL);
SMB_ASSERT(is_named_stream(smb_fname));
@@ -669,9 +744,9 @@ NTSTATUS open_stream_pathref_fsp(
return NT_STATUS_NO_MEMORY;
}
- status = fsp_new(conn, conn, &fsp);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
+ fsp = fsp_new(conn, conn);
+ if (fsp == NULL) {
+ goto nomem;
}
GetTimeOfDay(&fsp->open_time);
@@ -679,9 +754,9 @@ NTSTATUS open_stream_pathref_fsp(
fsp->fsp_flags.is_pathref = true;
- status = fsp_attach_smb_fname(fsp, &full_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
+ ok = fsp_attach_smb_fname(fsp, &full_fname);
+ if (!ok) {
+ goto nomem;
}
fsp_set_base_fsp(fsp, base_fsp);
@@ -707,15 +782,17 @@ NTSTATUS open_stream_pathref_fsp(
--
Samba Shared Repository