[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Mon Nov 27 19:31:02 UTC 2023
The branch, master has been updated
via 8f42b8431ef s3: smbd: Allow fchmod from the NFS-style mode ACL in set_nt_acl() for a SMB2 POSIX handle.
via 631e6aa0d02 smbd: bring back "smb3 unix extensions" option
via b124c2e1823 smbd: factor out smb2_negotiate_context_process_posix()
via 6e300ef7314 smbd: tweak POSIX check in smbd_do_qfilepathinfo()
via 55d98b29eb2 smbd: check is POSIX is enabled on the fsp in fsinfo_unix_valid_level()
via 01022d036f5 smbd: pass fsp to fsinfo_unix_valid_level()
via bca6f0298fe smbd: pass fsp to smbd_do_qfsinfo()
via 3f73bb591cf smbd: leave comment on broken SMB1 POSIX open handling of SMB_O_DIRECT
from 0b74adb3f01 samba-tool: Improve help messages for "samba-tool domain auth policy"
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 8f42b8431efcdeee9e270423bab9e111775430c9
Author: Jeremy Allison <jra at samba.org>
Date: Thu Mar 1 14:37:52 2018 -0800
s3: smbd: Allow fchmod from the NFS-style mode ACL in set_nt_acl() for a SMB2 POSIX handle.
To set a mode, send a one-element ACL.
Pair-Programmed-With: Ralph Boehme <slow at samba.org>
Signed-off-by: Jeremy Allison <jra at samba.org>
Signed-off-by: Ralph Boehme <slow at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Mon Nov 27 19:31:01 UTC 2023 on atb-devel-224
commit 631e6aa0d02756d6ebbc9dff5c9d81fdbca58d7f
Author: Ralph Boehme <slow at samba.org>
Date: Wed Nov 8 17:49:19 2023 +0100
smbd: bring back "smb3 unix extensions" option
This basically reverts commit b3cae8dcf192f65031f143e5bb9135c895611d98
with a few important differences:
* SMB3 UNIX extensions are always built, but disabled by default at runtime.
* They are globally enabled in the fileserver test environment.
* It's now a per-share option, so admins can selectively disable them
on a per-share basis. This allows clients to detect early that a share
doesn't support user mount requested POSIX and fail appropiately, passing
the failure to the requesting application (mount command).
Signed-off-by: Ralph Boehme <slow at samba.org>
commit b124c2e1823d96e51d9d19cb2ccb0286b923ac8d
Author: Ralph Boehme <slow at samba.org>
Date: Wed Nov 22 12:53:36 2023 +0100
smbd: factor out smb2_negotiate_context_process_posix()
No change in behaviour.
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 6e300ef73147e6549748593ce168e9763cd567be
Author: Ralph Boehme <slow at samba.org>
Date: Mon Nov 13 10:36:14 2023 +0100
smbd: tweak POSIX check in smbd_do_qfilepathinfo()
This check is only needed for SMB2, so check for that, and in the SMB2 codepath
we'll always have a valid fsp, so we can drop that check.
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 55d98b29eb294542cc4947573f233e0d5e6966cb
Author: Ralph Boehme <slow at samba.org>
Date: Mon Nov 13 10:35:30 2023 +0100
smbd: check is POSIX is enabled on the fsp in fsinfo_unix_valid_level()
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 01022d036f5c9c8296d9174240a58e437c84f848
Author: Ralph Boehme <slow at samba.org>
Date: Mon Nov 13 08:04:33 2023 +0100
smbd: pass fsp to fsinfo_unix_valid_level()
We need the fsp down in fsinfo_unix_valid_level(), pass it down.
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit bca6f0298fe7230bbf54950dab4329dee6cc9a51
Author: Ralph Boehme <slow at samba.org>
Date: Mon Nov 13 07:43:11 2023 +0100
smbd: pass fsp to smbd_do_qfsinfo()
We need the fsp down in fsinfo_unix_valid_level(), start passing it down.
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
commit 3f73bb591cf0ab4e7e305c9b58727790e54b32ed
Author: Ralph Boehme <slow at samba.org>
Date: Fri Nov 24 16:29:57 2023 +0100
smbd: leave comment on broken SMB1 POSIX open handling of SMB_O_DIRECT
Since e0814dc5082dd4ecca8a155e0ce24b073158fd92 the passed in attributes get
replaced by the mode in create_file_default().
As FILE_FLAG_NO_BUFFERING is never checked when doing the final IO, it doesn't
really matter.
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Jeremy Allison <jra at samba.org>
-----------------------------------------------------------------------
Summary of changes:
WHATSNEW.txt | 2 +-
.../smbdotconf/protocol/smb3unixextensions.xml | 9 ++
selftest/target/Samba3.pm | 1 +
source3/param/loadparm.c | 8 +-
source3/smbd/globals.h | 1 +
source3/smbd/smb1_trans2.c | 7 ++
source3/smbd/smb2_create.c | 4 +-
source3/smbd/smb2_getinfo.c | 1 +
source3/smbd/smb2_negprot.c | 97 +++++++++++++---------
source3/smbd/smb2_nttrans.c | 69 ++++++++++++++-
source3/smbd/smb2_trans2.c | 26 ++++--
11 files changed, 175 insertions(+), 50 deletions(-)
create mode 100644 docs-xml/smbdotconf/protocol/smb3unixextensions.xml
Changeset truncated at 500 lines:
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 2bd3f02e1dc..12dff08271c 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -57,7 +57,7 @@ smb.conf changes
Parameter Name Description Default
-------------- ----------- -------
- smb3 unix extensions removed always offered
+ smb3 unix extensions Per share -
KNOWN ISSUES
diff --git a/docs-xml/smbdotconf/protocol/smb3unixextensions.xml b/docs-xml/smbdotconf/protocol/smb3unixextensions.xml
new file mode 100644
index 00000000000..4c0319976a7
--- /dev/null
+++ b/docs-xml/smbdotconf/protocol/smb3unixextensions.xml
@@ -0,0 +1,9 @@
+<samba:parameter name="smb3 unix extensions"
+ context="S"
+ type="boolean"
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+ <description>
+ <para>Experimental SMB 3.1.1 Unix Extensions.</para>
+ </description>
+ <value type="default">no</value>
+</samba:parameter>
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index d56f12ee57a..4218a54358b 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1855,6 +1855,7 @@ sub setup_fileserver
my $ip4 = Samba::get_ipv4_addr("FILESERVER");
my $fileserver_options = "
+ smb3 unix extensions = yes
kernel change notify = yes
spotlight backend = elasticsearch
elasticsearch:address = $ip4
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 6b2f23ce633..797baa66309 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -4680,6 +4680,12 @@ void widelinks_warning(int snum)
"These parameters are incompatible. "
"Wide links will be disabled for this share.\n",
lp_const_servicename(snum));
+ } else if (lp_smb3_unix_extensions(snum)) {
+ DBG_ERR("Share '%s' has wide links and SMB3 Unix "
+ "extensions enabled. "
+ "These parameters are incompatible. "
+ "Wide links will be disabled for this share.\n",
+ lp_const_servicename(snum));
}
}
}
@@ -4687,7 +4693,7 @@ void widelinks_warning(int snum)
bool lp_widelinks(int snum)
{
/* wide links is always incompatible with unix extensions */
- if (lp_smb1_unix_extensions()) {
+ if (lp_smb1_unix_extensions() || lp_smb3_unix_extensions(snum)) {
/*
* Unless we have "allow insecure widelinks"
* turned on.
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 0c7e791711f..119483377c0 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -155,6 +155,7 @@ NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
uint16_t flags2,
unsigned int max_data_bytes,
size_t *fixed_portion,
+ struct files_struct *fsp,
struct smb_filename *smb_fname,
char **ppdata,
int *ret_data_len);
diff --git a/source3/smbd/smb1_trans2.c b/source3/smbd/smb1_trans2.c
index 77a5d361649..18caa41dce3 100644
--- a/source3/smbd/smb1_trans2.c
+++ b/source3/smbd/smb1_trans2.c
@@ -1681,6 +1681,7 @@ static void call_trans2qfsinfo(connection_struct *conn,
max_data_bytes,
&fixed_portion,
NULL,
+ NULL,
ppdata, &data_len);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -3461,6 +3462,12 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
access_mask |= FILE_APPEND_DATA;
}
if (wire_open_mode & SMB_O_DIRECT) {
+ /*
+ * BUG: this doesn't work anymore since
+ * e0814dc5082dd4ecca8a155e0ce24b073158fd92. But since
+ * FILE_FLAG_NO_BUFFERING isn't used at all in the IO codepath,
+ * it doesn't really matter.
+ */
attributes |= FILE_FLAG_NO_BUFFERING;
}
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index abcce5afb4f..8a40717235c 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -736,7 +736,9 @@ static NTSTATUS smbd_smb2_create_fetch_create_ctx(
state->svhdx = smb2_create_blob_find(
in_context_blobs, SVHDX_OPEN_DEVICE_CONTEXT);
}
- if (xconn->smb2.server.posix_extensions_negotiated) {
+ if (xconn->smb2.server.posix_extensions_negotiated &&
+ lp_smb3_unix_extensions(SNUM(state->smb1req->conn)))
+ {
/*
* Negprot only allowed this for proto>=3.11
*/
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 51283eb174e..55dca5e8031 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -473,6 +473,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
STR_UNICODE,
in_output_buffer_length,
&fixed_portion,
+ fsp,
fsp->fsp_name,
&data,
&data_size);
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index f9d5ae58b58..8f4167fc6a2 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -129,6 +129,61 @@ enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
return PROTOCOL_NONE;
}
+static NTSTATUS smb2_negotiate_context_process_posix(
+ const struct smb2_negotiate_contexts *in_c,
+ bool *posix)
+{
+ struct smb2_negotiate_context *in_posix = NULL;
+ const uint8_t *inbuf = NULL;
+ size_t inbuflen;
+ bool posix_found = false;
+ size_t ofs;
+ int cmp;
+
+ *posix = false;
+
+ if (!lp_smb3_unix_extensions(GLOBAL_SECTION_SNUM)) {
+ return NT_STATUS_OK;
+ }
+
+ in_posix = smb2_negotiate_context_find(in_c,
+ SMB2_POSIX_EXTENSIONS_AVAILABLE);
+ if (in_posix == NULL) {
+ return NT_STATUS_OK;
+ }
+
+ inbuf = in_posix->data.data;
+ inbuflen = in_posix->data.length;
+
+ /*
+ * For now the server only supports one variant.
+ * Check it's the right one.
+ */
+ if ((inbuflen % 16) != 0) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ SMB_ASSERT(strlen(SMB2_CREATE_TAG_POSIX) == 16);
+
+ for (ofs = 0; ofs < inbuflen; ofs += 16) {
+ cmp = memcmp(inbuf+ofs, SMB2_CREATE_TAG_POSIX, 16);
+ if (cmp == 0) {
+ posix_found = true;
+ break;
+ }
+ }
+
+ if (!posix_found) {
+ DBG_DEBUG("Client requested unknown SMB3 Unix extensions:\n");
+ dump_data(10, inbuf, inbuflen);
+ return NT_STATUS_OK;
+ }
+
+ DBG_DEBUG("Client requested SMB3 Unix extensions\n");
+ *posix = true;
+ return NT_STATUS_OK;
+}
+
struct smbd_smb2_request_process_negprot_state {
struct smbd_smb2_request *req;
DATA_BLOB outbody;
@@ -163,7 +218,6 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
struct smb2_negotiate_context *in_cipher = NULL;
struct smb2_negotiate_context *in_sign_algo = NULL;
struct smb2_negotiate_contexts out_c = { .num_contexts = 0, };
- struct smb2_negotiate_context *in_posix = NULL;
const struct smb311_capabilities default_smb3_capabilities =
smb311_capabilities_parse("server",
lp_server_smb3_signing_algorithms(),
@@ -181,6 +235,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
uint32_t max_read = lp_smb2_max_read();
uint32_t max_write = lp_smb2_max_write();
NTTIME now = timeval_to_nttime(&req->request_time);
+ bool posix = false;
bool ok;
status = smbd_smb2_request_verify_sizes(req, 0x24);
@@ -276,41 +331,9 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, status);
}
- in_posix = smb2_negotiate_context_find(
- &in_c,
- SMB2_POSIX_EXTENSIONS_AVAILABLE);
-
- if (in_posix != NULL) {
- const uint8_t *inbuf = in_posix->data.data;
- size_t inbuflen = in_posix->data.length;
- bool posix_found = false;
- /*
- * For now the server only supports one variant.
- * Check it's the right one.
- */
- if ((inbuflen % 16) != 0) {
- return smbd_smb2_request_error(
- req,
- NT_STATUS_INVALID_PARAMETER);
- }
- SMB_ASSERT(strlen(SMB2_CREATE_TAG_POSIX) == 16);
- for (ofs = 0; ofs < inbuflen; ofs += 16) {
- if (memcmp(inbuf + ofs,
- SMB2_CREATE_TAG_POSIX,
- 16) == 0) {
- posix_found = true;
- break;
- }
- }
- if (posix_found) {
- DBG_DEBUG("Client requested SMB2 unix "
- "extensions\n");
- } else {
- DBG_DEBUG("Client requested unknown "
- "SMB2 unix extensions:\n");
- dump_data(10, inbuf, inbuflen);
- in_posix = NULL;
- }
+ status = smb2_negotiate_context_process_posix(&in_c, &posix);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
}
}
@@ -688,7 +711,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
security_buffer = data_blob_const(NULL, 0);
#endif
- if (in_posix != NULL) {
+ if (posix) {
/* Client correctly negotiated SMB2 unix extensions. */
const uint8_t *buf = (const uint8_t *)SMB2_CREATE_TAG_POSIX;
status = smb2_negotiate_context_add(
diff --git a/source3/smbd/smb2_nttrans.c b/source3/smbd/smb2_nttrans.c
index 1312d9bfc36..bf5170f07d4 100644
--- a/source3/smbd/smb2_nttrans.c
+++ b/source3/smbd/smb2_nttrans.c
@@ -167,6 +167,50 @@ NTSTATUS set_sd(files_struct *fsp, struct security_descriptor *psd,
return status;
}
+static bool check_smb2_posix_chmod_ace(const struct files_struct *fsp,
+ uint32_t security_info_sent,
+ struct security_descriptor *psd,
+ mode_t *pmode)
+{
+ int cmp;
+
+ /*
+ * This must be an ACL with one ACE containing an
+ * MS NFS style mode entry coming in on a POSIX
+ * handle over SMB2+.
+ */
+ if (!fsp->conn->sconn->using_smb2) {
+ return false;
+ }
+
+ if (!(fsp->posix_flags & FSP_POSIX_FLAGS_OPEN)) {
+ return false;
+ }
+
+ if (!(security_info_sent & SECINFO_DACL)) {
+ return false;
+ }
+
+ if (psd->dacl == NULL) {
+ return false;
+ }
+
+ if (psd->dacl->num_aces != 1) {
+ return false;
+ }
+
+ cmp = dom_sid_compare_domain(&global_sid_Unix_NFS_Mode,
+ &psd->dacl->aces[0].trustee);
+ if (cmp != 0) {
+ return false;
+ }
+
+ *pmode = (mode_t)psd->dacl->aces[0].trustee.sub_auths[2];
+ *pmode &= (S_IRWXU | S_IRWXG | S_IRWXO);
+
+ return true;
+}
+
/****************************************************************************
Internal fn to set security descriptors from a data blob.
****************************************************************************/
@@ -176,6 +220,9 @@ NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len,
{
struct security_descriptor *psd = NULL;
NTSTATUS status;
+ bool do_chmod = false;
+ mode_t smb2_posix_mode = 0;
+ int ret;
if (sd_len == 0) {
return NT_STATUS_INVALID_PARAMETER;
@@ -187,7 +234,27 @@ NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len,
return status;
}
- return set_sd(fsp, psd, security_info_sent);
+ do_chmod = check_smb2_posix_chmod_ace(fsp,
+ security_info_sent,
+ psd,
+ &smb2_posix_mode);
+ if (!do_chmod) {
+ return set_sd(fsp, psd, security_info_sent);
+ }
+
+ TALLOC_FREE(psd);
+
+ ret = SMB_VFS_FCHMOD(fsp, smb2_posix_mode);
+ if (ret != 0) {
+ status = map_nt_error_from_unix(errno);
+ DBG_ERR("smb2_posix_chmod [%s] [%04o] failed: %s\n",
+ fsp_str_dbg(fsp),
+ (unsigned)smb2_posix_mode,
+ nt_errstr(status));
+ return status;
+ }
+
+ return NT_STATUS_OK;
}
/****************************************************************************
diff --git a/source3/smbd/smb2_trans2.c b/source3/smbd/smb2_trans2.c
index 0dc3fa62b3f..3d13d05673b 100644
--- a/source3/smbd/smb2_trans2.c
+++ b/source3/smbd/smb2_trans2.c
@@ -1948,10 +1948,13 @@ static void samba_extended_info_version(struct smb_extended_info *extended_info)
}
static bool fsinfo_unix_valid_level(connection_struct *conn,
+ struct files_struct *fsp,
uint16_t info_level)
{
if (conn->sconn->using_smb2 &&
- info_level == SMB2_FS_POSIX_INFORMATION_INTERNAL) {
+ fsp->posix_flags == FSP_POSIX_FLAGS_OPEN &&
+ info_level == SMB2_FS_POSIX_INFORMATION_INTERNAL)
+ {
return true;
}
#if defined(SMB1SERVER)
@@ -1963,6 +1966,9 @@ static bool fsinfo_unix_valid_level(connection_struct *conn,
return false;
}
+/*
+ * fsp is only valid for SMB2.
+ */
NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
connection_struct *conn,
TALLOC_CTX *mem_ctx,
@@ -1970,6 +1976,7 @@ NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
uint16_t flags2,
unsigned int max_data_bytes,
size_t *fixed_portion,
+ struct files_struct *fsp,
struct smb_filename *fname,
char **ppdata,
int *ret_data_len)
@@ -2311,14 +2318,14 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
/* we need to fake up a fsp here,
* because its not send in this call
*/
- files_struct fsp;
+ files_struct tmpfsp;
SMB_NTQUOTA_STRUCT quotas;
- ZERO_STRUCT(fsp);
+ ZERO_STRUCT(tmpfsp);
ZERO_STRUCT(quotas);
- fsp.conn = conn;
- fsp.fnum = FNUM_FIELD_INVALID;
+ tmpfsp.conn = conn;
+ tmpfsp.fnum = FNUM_FIELD_INVALID;
/* access check */
if (get_current_uid(conn) != 0) {
@@ -2329,7 +2336,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
return NT_STATUS_ACCESS_DENIED;
}
- status = vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE,
+ status = vfs_get_ntquota(&tmpfsp, SMB_USER_FS_QUOTA_TYPE,
NULL, "as);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
@@ -2466,7 +2473,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
int rc;
struct vfs_statvfs_struct svfs;
- if (!fsinfo_unix_valid_level(conn, info_level)) {
+ if (!fsinfo_unix_valid_level(conn, fsp, info_level)) {
return NT_STATUS_INVALID_LEVEL;
}
@@ -2993,8 +3000,9 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
ok = true;
}
- if ((fsp != NULL) &&
- (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN)) {
+ if (conn->sconn->using_smb2 &&
+ (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN))
+ {
DBG_DEBUG("SMB2 posix open\n");
ok = true;
}
--
Samba Shared Repository
More information about the samba-cvs
mailing list