1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-11 16:58:40 +03:00

Compare commits

...

17 Commits

Author SHA1 Message Date
Ralph Boehme
6d71edab5a smbd: use fsctl_get_reparse_point() in smb3_file_posix_information_init()
This allows returning the POSIX type info from fsctl_get_reparse_point().

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>

Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Wed Nov 27 19:32:45 UTC 2024 on atb-devel-224
2024-11-27 19:32:45 +00:00
Ralph Boehme
b51a827e47 smbd: move calling fsctl_get_reparse_tag() into smb3_file_posix_information_init()
This already fixes SMB2-GETINFO with POSIX infolevel to return the reparse tag
of reparse points.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:29 +00:00
Ralph Boehme
a10755881e smbd: simplify smb3_file_posix_information_init()
The dos attributes are already setup by fdos_mode(). Still assert
FILE_ATTRIBUTE_REPARSE_POINT is correctly set just in case.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:29 +00:00
Ralph Boehme
306d4e7fff smbd: fix DOS attributes for reparse points in fdos_mode()
Reparse have only FILE_ATTRIBUTE_REPARSE_POINT set, but never
FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_DIRECTORY at the same time.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:29 +00:00
Ralph Boehme
21ef00d0f0 tests: test POSIX file type on reparse point
Create a symlink reparse point over SMB2. Then query file info over SMB2 and
check the POSIX file type is correctly assigned in the POSIX info levels.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:29 +00:00
Ralph Boehme
26e8105518 tests: check reparse tag and POSIX file type from query-file with POSIX infolevel
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:29 +00:00
Ralph Boehme
44a2458ca4 tests: fix test teardown/cleanup of test_create_reparse_directory()
This kept failing in a local make test not being able to cleanup the test
directory in the *subsequent* test test_create_reparse_nonempty_directory().

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:28 +00:00
Ralph Boehme
8c468c6e5c tests: prepare reparsepoints.py for using POSIX on the SMB2 connection
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:28 +00:00
Ralph Boehme
d46bfc5d50 tests: move wire_mode_to_unix() to libsmb.py
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:28 +00:00
Ralph Boehme
02cc280710 pylibsmb: implement getinfo level FSCC_FILE_POSIX_INFORMATION
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:28 +00:00
Ralph Boehme
239d8f463b smbd: rename SMB2_FS_POSIX_INFORMATION to FSCC_FS_POSIX_INFORMATION
Streamline the info-level defines. Also get rid of
SMB2_FS_POSIX_INFORMATION_INTERNAL which is not needed for an info-level that
is exclusive to SMB2.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:28 +00:00
Ralph Boehme
27198998ed smbd: rename SMB2_FILE_POSIX_INFORMATION to FSCC_FILE_POSIX_INFORMATION
Streamline the info-level defines. Also get rid of
SMB2_FILE_POSIX_INFORMATION_INTERNAL which is not needed for an info-level that
is exclusive to SMB2.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:28 +00:00
Ralph Boehme
8eccfbea7d smbd: use NT_PASSTHROUGH_OFFSET in a few places
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
2024-11-27 18:22:28 +00:00
Andreas Schneider
a882e86104 gitlab-ci: Fix building debian 32bit images
Trying to pull registry-1.docker.io/i386/debian:12...
Error: creating build container: choosing an image from manifest list
docker://registry-1.docker.io/i386/debian:12: no image found in image index for
architecture "amd64", variant "", OS "linux"

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>

Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Wed Nov 27 16:32:07 UTC 2024 on atb-devel-224
2024-11-27 16:32:07 +00:00
Andreas Schneider
475896028b gitlab-ci: Move to Fedora 41
Python 3.13 removed the `crypt` module. I can work around it on Fedora 41, but
we need to address this better sooner than later.

See also https://bugzilla.samba.org/show_bug.cgi?id=15756

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
2024-11-27 15:33:35 +00:00
Andreas Schneider
be5531aaec selftest: Allow to use SHA1 with OpenSSL for selftest
This is needed for samba.tests.krb5.pkinit_tests with sha1.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
2024-11-27 15:33:35 +00:00
Andreas Schneider
6c619c77c9 python: Fix length of Common Name x509 attribute
File "bin/python/samba/tests/krb5/pkinit_tests.py", line 1496, in
create_certificate
  x509.NameAttribute(NameOID.COMMON_NAME,
  ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
                     f'{cert_name}/emailAddress={cert_name}'),
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib64/python3.13/site-packages/cryptography/x509/name.py",
line 152, in __init__
  raise ValueError(msg)
ValueError: Attribute's length must be >= 1 and <= 64, but it was 84

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
2024-11-27 15:33:35 +00:00
25 changed files with 384 additions and 97 deletions

View File

@ -47,7 +47,7 @@ variables:
# Set this to the contents of bootstrap/sha1sum.txt
# which is generated by bootstrap/template.py --render
#
SAMBA_CI_CONTAINER_TAG: 936722ecb26bedf6ea0acd9228963ce45ed419d4
SAMBA_CI_CONTAINER_TAG: d101907857587b6421907c45676497c336d45ea7
#
# We use the ubuntu2204 image as default as
# it matches what we have on atb-devel-224
@ -66,7 +66,7 @@ variables:
SAMBA_CI_CONTAINER_IMAGE_opensuse155: opensuse155
SAMBA_CI_CONTAINER_IMAGE_rocky8: rocky8
SAMBA_CI_CONTAINER_IMAGE_centos9s: centos9s
SAMBA_CI_CONTAINER_IMAGE_fedora40: fedora40
SAMBA_CI_CONTAINER_IMAGE_fedora41: fedora41
include:
# The image creation details are specified in a separate file
@ -267,13 +267,13 @@ samba-def-build:
samba-mit-build:
extends: .shared_template_build_only
variables:
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_fedora40}
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_fedora41}
stage: build_first
.needs_samba-mit-build:
extends: .shared_template_test_only
variables:
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_fedora40}
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_fedora41}
needs:
- job: samba-mit-build
artifacts: true
@ -321,7 +321,7 @@ samba:
samba-mitkrb5:
extends: .shared_template
variables:
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_fedora40}
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_fedora41}
samba-minimal-smbd:
extends: .shared_template
@ -391,7 +391,7 @@ samba-addc-mit-4b:
samba-fips:
extends: .shared_template
variables:
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_fedora40}
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_fedora41}
samba-codecheck:
extends: .shared_template
@ -672,10 +672,10 @@ centos9s-samba-o3:
variables:
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_centos9s}
fedora40-samba-o3:
fedora41-samba-o3:
extends: .samba-o3-template
variables:
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_fedora40}
SAMBA_CI_JOB_IMAGE: ${SAMBA_CI_CONTAINER_IMAGE_fedora41}
#
# Keep the samba-o3 sections at the end ...

View File

@ -10,6 +10,7 @@
variables:
SAMBA_CI_IS_BROKEN_IMAGE: "no"
SAMBA_CI_TEST_JOB: "samba-o3"
SAMBA_CI_PLATFORM: "linux/amd64"
before_script:
# install prerequisites
- dnf install -qy diffutils
@ -27,7 +28,7 @@
script: |
set -xueo pipefail
ci_image_name=samba-ci-${CI_JOB_NAME}
podman build -t ${ci_image_name} --build-arg SHA1SUM=${SAMBA_CI_CONTAINER_TAG} bootstrap/generated-dists/${CI_JOB_NAME}
podman build --platform ${SAMBA_CI_PLATFORM} --tag ${ci_image_name} --build-arg SHA1SUM=${SAMBA_CI_CONTAINER_TAG} bootstrap/generated-dists/${CI_JOB_NAME}
ci_image_path="${SAMBA_CI_CONTAINER_REGISTRY}/${ci_image_name}"
timestamp=$(date +%Y%m%d%H%M%S)
container_hash=$(podman image inspect --format='{{ .Id }}' ${ci_image_name} | cut -c 1-9)
@ -98,13 +99,14 @@ debian11:
debian12:
extends: .build_image_template
fedora40:
fedora41:
extends: .build_image_template
debian11-32bit:
extends: .build_image_template
variables:
SAMBA_CI_TEST_JOB: "samba-32bit"
SAMBA_CI_PLATFORM: "linux/i386"
rocky8:
extends: .build_image_template

View File

@ -159,6 +159,10 @@ PKGS = [
('', 'python3-libsemanage'),
('', 'python3-policycoreutils'),
# A copy of the `crypt` module that was removed in Python 3.13
# See also https://bugzilla.samba.org/show_bug.cgi?id=15756
('', 'python3-crypt-r'),
# perl
('libparse-yapp-perl', 'perl-Parse-Yapp'),
('perl-modules', ''),
@ -457,7 +461,7 @@ DEB_DISTS = {
}
},
'debian11-32bit': {
'docker_image': 'registry-1.docker.io/i386/debian:11',
'docker_image': 'debian:11', # specify the platform in .gitlab-ci.yaml
'vagrant_box': 'debian/bullseye32',
'replace': {
'language-pack-en': '', # included in locales
@ -534,6 +538,7 @@ RPM_DISTS = {
'ShellCheck': '',
'shfmt': '',
'codespell': '',
'python3-crypt-r': '',
}
},
'centos9s': {
@ -553,11 +558,12 @@ RPM_DISTS = {
'codespell': '',
'libcephfs-devel': '', # not available anymore
'curl': '', # Use installed curl-minimal
'python3-crypt-r': '',
}
},
'fedora40': {
'docker_image': 'quay.io/fedora/fedora:40',
'vagrant_box': 'fedora/40-cloud-base',
'fedora41': {
'docker_image': 'quay.io/fedora/fedora:41',
'vagrant_box': 'fedora/41-cloud-base',
'bootstrap': DNF_BOOTSTRAP,
'replace': {
'lsb-release': 'redhat-lsb',
@ -581,6 +587,7 @@ RPM_DISTS = {
'keyutils-libs-devel': 'keyutils-devel',
'krb5-workstation': 'krb5-client',
'python3-libsemanage': 'python3-semanage',
'python3-crypt-r': '',
'openldap-devel': 'openldap2-devel',
'perl-Archive-Tar': 'perl-Archive-Tar-Wrapper',
'perl-JSON-Parse': 'perl-JSON-XS',

View File

@ -45,11 +45,11 @@ Vagrant.configure("2") do |config|
v.vm.provision :shell, path: "debian12-32bit/locale.sh"
end
config.vm.define "fedora40" do |v|
v.vm.box = "fedora/40-cloud-base"
v.vm.hostname = "fedora40"
v.vm.provision :shell, path: "fedora40/bootstrap.sh"
v.vm.provision :shell, path: "fedora40/locale.sh"
config.vm.define "fedora41" do |v|
v.vm.box = "fedora/41-cloud-base"
v.vm.hostname = "fedora41"
v.vm.provision :shell, path: "fedora41/bootstrap.sh"
v.vm.provision :shell, path: "fedora41/locale.sh"
end
config.vm.define "opensuse155" do |v|

View File

@ -3,7 +3,7 @@
# See also bootstrap/config.py
#
FROM registry-1.docker.io/i386/debian:11
FROM debian:11
# pass in with --build-arg while build
ARG SHA1SUM

View File

@ -3,7 +3,7 @@
# See also bootstrap/config.py
#
FROM quay.io/fedora/fedora:40
FROM quay.io/fedora/fedora:41
# pass in with --build-arg while build
ARG SHA1SUM

View File

@ -92,6 +92,7 @@ dnf install -y \
procps-ng \
psmisc \
python3 \
python3-crypt-r \
python3-cryptography \
python3-dateutil \
python3-devel \

View File

@ -81,6 +81,7 @@ packages:
- procps-ng
- psmisc
- python3
- python3-crypt-r
- python3-cryptography
- python3-dateutil
- python3-devel

View File

@ -1 +1 @@
936722ecb26bedf6ea0acd9228963ce45ed419d4
d101907857587b6421907c45676497c336d45ea7

View File

@ -417,6 +417,6 @@ enum smb_whoami_flags {
#define INFO_LEVEL_IS_UNIX(level) ((((level) >= MIN_UNIX_INFO_LEVEL) && \
((level) <= MAX_UNIX_INFO_LEVEL)) || \
((level) == SMB2_FILE_POSIX_INFORMATION_INTERNAL))
((level) == FSCC_FILE_POSIX_INFORMATION))
#endif /* __SMB_UNIX_EXT_H__ */

View File

@ -1493,8 +1493,7 @@ class PkInitTests(KDCBaseTest):
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, 'SambaState'),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'SambaSelfTesting'),
x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, 'Users'),
x509.NameAttribute(NameOID.COMMON_NAME,
f'{cert_name}/emailAddress={cert_name}'),
x509.NameAttribute(NameOID.COMMON_NAME, f'{cert_name}'),
]))
# The new certificate must be issued by the root CA.

View File

@ -24,6 +24,7 @@ from samba import credentials
from samba import (ntstatus,NTSTATUSError)
import samba.tests
import os
import stat
class LibsmbTests(samba.tests.TestCase):
@ -53,3 +54,10 @@ class LibsmbTests(samba.tests.TestCase):
elif not (e.args[0] == ntstatus.NT_STATUS_OBJECT_NAME_NOT_FOUND or
e.args[0] == ntstatus.NT_STATUS_OBJECT_PATH_NOT_FOUND):
raise
def wire_mode_to_unix(self, wire):
mode = libsmb.wire_mode_to_unix(wire)
type = stat.S_IFMT(mode)
perms = mode & (stat.S_IRWXU|stat.S_IRWXG|stat.S_IRWXO|
stat.S_ISUID|stat.S_ISGID|stat.S_ISVTX)
return (type, perms)

View File

@ -22,9 +22,12 @@ from samba import reparse_symlink
import samba.tests.libsmb
import stat
def posix_context(mode):
return (libsmb.SMB2_CREATE_TAG_POSIX, mode.to_bytes(4, 'little'))
class ReparsePoints(samba.tests.libsmb.LibsmbTests):
def connection(self):
def connection(self, posix=False):
share = samba.tests.env_get_var_value("SHARENAME", allow_missing=True)
if not share:
share = "tmp"
@ -34,6 +37,7 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
share,
self.lp,
self.creds,
posix=posix,
force_smb1=smb1)
return conn
@ -233,10 +237,14 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
err = e.args[0]
if (err != ntstatus.NT_STATUS_ACCESS_DENIED):
raise
finally:
conn.close(dir_fd)
self.clean_file(conn, dirname)
if (err == ntstatus.NT_STATUS_ACCESS_DENIED):
self.fail("Could not set reparse point on directory")
conn.delete_on_close(fd, 1)
conn.close(dir_fd)
self.clean_file(conn, dirname)
return
with self.assertRaises(NTSTATUSError) as e:
@ -397,22 +405,30 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
def do_test_nfs_reparse(self, filename, filetype, nfstype):
"""Test special file reparse tag"""
smb2 = self.connection()
smb2 = self.connection(posix=True)
smb1 = self.connection_posix()
self.clean_file(smb2, filename)
smb1.mknod(filename, filetype | 0o755)
fd = smb2.create(
fd,_,_ = smb2.create_ex(
filename,
DesiredAccess=sec.SEC_FILE_READ_ATTRIBUTE|sec.SEC_STD_DELETE,
CreateOptions=libsmb.FILE_OPEN_REPARSE_POINT,
CreateDisposition=libsmb.FILE_OPEN)
CreateDisposition=libsmb.FILE_OPEN,
ShareAccess=(libsmb.FILE_SHARE_READ|libsmb.FILE_SHARE_WRITE|libsmb.FILE_SHARE_DELETE),
CreateContexts=[posix_context(0o600)])
smb2.delete_on_close(fd, 1)
info = smb2.qfileinfo(fd, libsmb.FSCC_FILE_ATTRIBUTE_TAG_INFORMATION);
self.assertEqual(info['tag'], libsmb.IO_REPARSE_TAG_NFS)
info = smb2.qfileinfo(fd, libsmb.FSCC_FILE_POSIX_INFORMATION);
self.assertEqual(info['reparse_tag'], libsmb.IO_REPARSE_TAG_NFS)
type, perms = self.wire_mode_to_unix(info['perms'])
self.assertEqual(type, filetype)
reparse = smb2.fsctl(fd, libsmb.FSCTL_GET_REPARSE_POINT, b'', 1024)
(tag, ) = reparse_symlink.get(reparse)
self.assertEqual(tag, nfstype)
@ -425,6 +441,34 @@ class ReparsePoints(samba.tests.libsmb.LibsmbTests):
"""Test SOCK reparse tag"""
self.do_test_nfs_reparse('sock', stat.S_IFSOCK, 'NFS_SPECFILE_SOCK')
def test_reparsepoint_posix_type(self):
conn = self.connection(posix=True)
filename = 'reparse'
self.clean_file(conn, filename)
fd,_,_ = conn.create_ex(
filename,
DesiredAccess=sec.SEC_FILE_WRITE_ATTRIBUTE,
CreateDisposition=libsmb.FILE_CREATE,
CreateContexts=[posix_context(0o600)])
b = reparse_symlink.symlink_put("y", "y", 0, 0)
conn.fsctl(fd, libsmb.FSCTL_SET_REPARSE_POINT, b, 0)
conn.close(fd)
dirents = conn.list("", filename,info_level=libsmb.SMB2_FIND_POSIX_INFORMATION)
self.assertEqual(
dirents[0]["attrib"],
libsmb.FILE_ATTRIBUTE_REPARSE_POINT|
libsmb.FILE_ATTRIBUTE_ARCHIVE)
self.assertEqual(
dirents[0]["reparse_tag"],
libsmb.IO_REPARSE_TAG_SYMLINK)
type, perms = self.wire_mode_to_unix(dirents[0]['perms'])
self.assertEqual(type, stat.S_IFLNK)
self.clean_file(conn, filename)
if __name__ == '__main__':
import unittest
unittest.main()

View File

@ -70,13 +70,6 @@ class Smb3UnixTests(samba.tests.libsmb.LibsmbTests):
return (conn1, conn2)
def wire_mode_to_unix(self, wire):
mode = libsmb.wire_mode_to_unix(wire)
type = stat.S_IFMT(mode)
perms = mode & (stat.S_IRWXU|stat.S_IRWXG|stat.S_IRWXO|
stat.S_ISUID|stat.S_ISGID|stat.S_ISVTX)
return (type, perms)
def test_negotiate_context_posix(self):
c = libsmb.Conn(
self.server_ip,

View File

@ -455,6 +455,10 @@ if ($opt_mitkrb5 == 1) {
$ENV{KRB5RCACHETYPE} = "none";
}
# Enable support for SHA1 in OpenSSL
# This is required e.g. for pkinit sha1 tests
$ENV{OPENSSL_ENABLE_SHA1_SIGNATURES} = 1;
# After this many seconds, the server will self-terminate. All tests
# must terminate in this time, and testenv will only stay alive this
# long

View File

@ -341,8 +341,7 @@ Byte offset Type name description
#define FSCC_FILE_MAXIMUM_INFORMATION 55
/* As yet undefined FSCC_ code for POSIX info level. */
#define SMB2_FILE_POSIX_INFORMATION 100
#define SMB2_FS_POSIX_INFORMATION 100
#define FSCC_FILE_POSIX_INFORMATION 100
/* MS-FSCC 2.4 File System Information Classes */
@ -356,6 +355,9 @@ Byte offset Type name description
#define FSCC_FS_OBJECTID_INFORMATION 8
#define FSCC_FS_SECTOR_SIZE_INFORMATION 11
/* As yet undefined FSCC_ code for POSIX info level. */
#define FSCC_FS_POSIX_INFORMATION 100
/* NT passthrough levels... */
#define NT_PASSTHROUGH_OFFSET 1000
@ -412,8 +414,6 @@ Byte offset Type name description
#define SMB2_FILE_RENAME_INFORMATION_INTERNAL (FSCC_FILE_RENAME_INFORMATION + SMB2_INFO_SPECIAL)
#define SMB2_FILE_FULL_EA_INFORMATION (FSCC_FILE_FULL_EA_INFORMATION + SMB2_INFO_SPECIAL)
#define SMB2_FILE_ALL_INFORMATION (FSCC_FILE_ALL_INFORMATION + SMB2_INFO_SPECIAL)
#define SMB2_FILE_POSIX_INFORMATION_INTERNAL (SMB2_FILE_POSIX_INFORMATION + SMB2_INFO_SPECIAL)
#define SMB2_FS_POSIX_INFORMATION_INTERNAL 1100
/* NT passthrough levels for qfsinfo. */

View File

@ -5145,7 +5145,7 @@ static void cli_smb2_get_posix_fs_info_opened(struct tevent_req *subreq)
state->cli,
state->fnum,
SMB2_0_INFO_FILESYSTEM, /* in_info_type */
SMB2_FS_POSIX_INFORMATION, /* in_file_info_class */
FSCC_FS_POSIX_INFORMATION, /* in_file_info_class */
0xFFFF, /* in_max_output_length */
NULL, /* in_input_buffer */
0, /* in_additional_info */

View File

@ -60,6 +60,7 @@ c = libsmb.Conn("127.0.0.1",
#include "trans2.h"
#include "libsmb/clirap.h"
#include "librpc/rpc/pyrpc_util.h"
#include "librpc/gen_ndr/ndr_security.h"
#define LIST_ATTRIBUTE_MASK \
(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN)
@ -1388,6 +1389,129 @@ static PyObject *py_cli_qfileinfo(struct py_cli_state *self, PyObject *args)
(unsigned long long)tag);
break;
}
case FSCC_FILE_POSIX_INFORMATION: {
size_t data_off = 0;
time_t btime;
time_t atime;
time_t mtime;
time_t ctime;
uint64_t size;
uint64_t alloc_size;
uint32_t attr;
uint64_t ino;
uint32_t dev;
uint32_t nlinks;
uint32_t reparse_tag;
uint32_t mode;
size_t sid_size;
enum ndr_err_code ndr_err;
struct dom_sid owner, group;
struct dom_sid_buf owner_buf, group_buf;
if (num_rdata < 80) {
PyErr_SetNTSTATUS(NT_STATUS_INVALID_NETWORK_RESPONSE);
return NULL;
}
btime = nt_time_to_unix(PULL_LE_U64(rdata, data_off));
data_off += 8;
atime = nt_time_to_unix(PULL_LE_U64(rdata, data_off));
data_off += 8;
mtime = nt_time_to_unix(PULL_LE_U64(rdata, data_off));
data_off += 8;
ctime = nt_time_to_unix(PULL_LE_U64(rdata, data_off));
data_off += 8;
size = PULL_LE_U64(rdata, data_off);
data_off += 8;
alloc_size = PULL_LE_U64(rdata, data_off);
data_off += 8;
attr = PULL_LE_U32(rdata, data_off);
data_off += 4;
ino = PULL_LE_U64(rdata, data_off);
data_off += 8;
dev = PULL_LE_U32(rdata, data_off);
data_off += 4;
/* 4 bytes reserved */
data_off += 4;
nlinks = PULL_LE_U32(rdata, data_off);
data_off += 4;
reparse_tag = PULL_LE_U32(rdata, data_off);
data_off += 4;
mode = PULL_LE_U32(rdata, data_off);
data_off += 4;
ndr_err = ndr_pull_struct_blob_noalloc(
rdata + data_off,
num_rdata - data_off,
&owner,
(ndr_pull_flags_fn_t)ndr_pull_dom_sid,
&sid_size);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
PyErr_SetNTSTATUS(NT_STATUS_INVALID_NETWORK_RESPONSE);
return NULL;
}
if (data_off + sid_size < data_off ||
data_off + sid_size > num_rdata)
{
PyErr_SetNTSTATUS(NT_STATUS_INVALID_NETWORK_RESPONSE);
return NULL;
}
data_off += sid_size;
ndr_err = ndr_pull_struct_blob_noalloc(
rdata + data_off,
num_rdata - data_off,
&group,
(ndr_pull_flags_fn_t)ndr_pull_dom_sid,
&sid_size);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
PyErr_SetNTSTATUS(NT_STATUS_INVALID_NETWORK_RESPONSE);
return NULL;
}
result = Py_BuildValue(
"{s:i," /* attr */
"s:K,s:K,s:K,s:K," /* dates */
"s:K,s:K," /* sizes */
"s:K,s:K,s:K," /* ino, dev, nlinks */
"s:K,s:K," /* tag, mode */
"s:s,s:s}", /* owner, group */
"attrib",
attr,
"btime",
(unsigned long long)btime,
"atime",
(unsigned long long)atime,
"mtime",
(unsigned long long)mtime,
"ctime",
(unsigned long long)ctime,
"allocation_size",
(unsigned long long)alloc_size,
"size",
(unsigned long long)size,
"ino",
(unsigned long long)ino,
"dev",
(unsigned long long)dev,
"nlink",
(unsigned long long)nlinks,
"reparse_tag",
(unsigned long long)reparse_tag,
"perms",
(unsigned long long)mode,
"owner_sid",
dom_sid_str_buf(&owner, &owner_buf),
"group_sid",
dom_sid_str_buf(&group, &group_buf));
break;
}
default:
result = PyBytes_FromStringAndSize((char *)rdata, num_rdata);
break;
@ -3222,6 +3346,7 @@ MODULE_INIT_FUNC(libsmb_samba_cwrapper)
ADD_FLAGS(FSCC_FILE_ID_GLOBAL_TX_DIRECTORY_INFORMATION);
ADD_FLAGS(FSCC_FILE_STANDARD_LINK_INFORMATION);
ADD_FLAGS(FSCC_FILE_MAXIMUM_INFORMATION);
ADD_FLAGS(FSCC_FILE_POSIX_INFORMATION);
#define ADD_STRING(val) PyModule_AddObject(m, #val, PyBytes_FromString(val))

View File

@ -687,7 +687,9 @@ static uint32_t dos_mode_post(uint32_t dosmode,
dosmode |= dos_mode_from_name(fsp->conn, smb_fname->base_name, dosmode);
if (S_ISDIR(smb_fname->st.st_ex_mode)) {
dosmode |= FILE_ATTRIBUTE_DIRECTORY;
if (!(dosmode & FILE_ATTRIBUTE_REPARSE_POINT)) {
dosmode |= FILE_ATTRIBUTE_DIRECTORY;
}
} else if (dosmode == 0) {
dosmode = FILE_ATTRIBUTE_NORMAL;
}
@ -736,13 +738,12 @@ uint32_t fdos_mode(struct files_struct *fsp)
* Everybody else wants to see symlinks as
* reparse points
*/
result = FILE_ATTRIBUTE_NORMAL |
FILE_ATTRIBUTE_REPARSE_POINT;
result = FILE_ATTRIBUTE_REPARSE_POINT;
}
break;
default:
return FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_REPARSE_POINT;
return FILE_ATTRIBUTE_REPARSE_POINT;
break;
}

View File

@ -1223,10 +1223,9 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
DATA_BLOB *new_cookie);
struct smb3_file_posix_information;
void smb3_file_posix_information_init(
NTSTATUS smb3_file_posix_information_init(
connection_struct *conn,
const struct stat_ex *st,
uint32_t reparse_tag,
const struct smb_filename *smb_fname,
uint32_t dos_attributes,
struct smb3_file_posix_information *dst);

View File

@ -338,17 +338,17 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
file_info_level = SMB2_FILE_ALL_INFORMATION;
break;
case SMB2_FILE_POSIX_INFORMATION:
case FSCC_FILE_POSIX_INFORMATION:
if (!fsp->fsp_flags.posix_open) {
tevent_req_nterror(req, NT_STATUS_INVALID_LEVEL);
return tevent_req_post(req, ev);
}
file_info_level = SMB2_FILE_POSIX_INFORMATION_INTERNAL;
file_info_level = in_file_info_class;
break;
default:
/* the levels directly map to the passthru levels */
file_info_level = in_file_info_class + 1000;
file_info_level = in_file_info_class + NT_PASSTHROUGH_OFFSET;
break;
}
@ -465,8 +465,15 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
int data_size = 0;
size_t fixed_portion;
/* the levels directly map to the passthru levels */
file_info_level = in_file_info_class + 1000;
switch (in_file_info_class) {
case FSCC_FS_POSIX_INFORMATION:
file_info_level = in_file_info_class;
break;
default:
/* the levels directly map to the passthru levels */
file_info_level = in_file_info_class + NT_PASSTHROUGH_OFFSET;
break;
}
status = smbd_do_qfsinfo(smb2req->xconn, conn, state,
file_info_level,

View File

@ -23,14 +23,132 @@
#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/smb3posix.h"
#include "libcli/security/security.h"
#include "source3/modules/util_reparse.h"
#include "libcli/smb/reparse.h"
void smb3_file_posix_information_init(
static NTSTATUS reparse_buffer_parse_posix_type(uint32_t reparse_tag,
uint8_t *data,
uint32_t len,
mode_t *type)
{
struct reparse_data_buffer *reparse = NULL;
NTSTATUS status;
if (reparse_tag == IO_REPARSE_TAG_SYMLINK) {
*type = S_IFLNK;
return NT_STATUS_OK;
}
if (reparse_tag != IO_REPARSE_TAG_NFS) {
/*
* Clients can create reparse points with arbitrary tags, return
* anything that is not a NFS one (or symlink) as S_IFREG.
*/
DBG_INFO("Unhandled NFS reparse tag: 0x%" PRIx32 "\n",
reparse->tag);
*type = S_IFREG;
return NT_STATUS_OK;
}
reparse = talloc_zero(talloc_tos(), struct reparse_data_buffer);
if (reparse == NULL) {
DBG_ERR("talloc_zero() failed\n");
return NT_STATUS_NO_MEMORY;
}
status = reparse_data_buffer_parse(reparse, reparse, data, len);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(reparse);
return status;
}
switch (reparse->parsed.nfs.type) {
case NFS_SPECFILE_CHR:
*type = S_IFCHR;
break;
case NFS_SPECFILE_BLK:
*type = S_IFBLK;
break;
case NFS_SPECFILE_FIFO:
*type = S_IFIFO;
break;
case NFS_SPECFILE_SOCK:
*type = S_IFSOCK;
break;
default:
DBG_ERR("Unhandled NFS reparse type: 0x%" PRIx64 "\n",
reparse->parsed.nfs.type);
TALLOC_FREE(reparse);
return NT_STATUS_REPARSE_POINT_NOT_RESOLVED;
}
TALLOC_FREE(reparse);
return status;
}
NTSTATUS smb3_file_posix_information_init(
connection_struct *conn,
const struct stat_ex *st,
uint32_t reparse_tag,
const struct smb_filename *smb_fname,
uint32_t dos_attributes,
struct smb3_file_posix_information *dst)
{
const struct stat_ex *st = &smb_fname->st;
mode_t mode = st->st_ex_mode;
uint32_t reparse_tag = 0;
NTSTATUS status;
switch (mode & S_IFMT) {
case S_IFREG:
case S_IFDIR:
break;
default:
/*
* All non-directory or regular files are reported
* as reparse points. Client may or may not be able
* to access these. This should already be set by
* fdos_mode(), assert this.
*/
SMB_ASSERT(dos_attributes & FILE_ATTRIBUTE_REPARSE_POINT);
break;
}
if (dos_attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
uint8_t *reparse_data = NULL;
uint32_t reparse_len;
mode_t type = S_IFREG;
status = fsctl_get_reparse_point(smb_fname->fsp,
talloc_tos(),
&reparse_tag,
&reparse_data,
UINT32_MAX,
&reparse_len);
if (!NT_STATUS_IS_OK(status)) {
DBG_DEBUG("Could not get reparse point for %s: %s\n",
smb_fname_str_dbg(smb_fname),
nt_errstr(status));
return status;
}
status = reparse_buffer_parse_posix_type(reparse_tag,
reparse_data,
reparse_len,
&type);
TALLOC_FREE(reparse_data);
if (!NT_STATUS_IS_OK(status)) {
DBG_DEBUG("Could not parse reparse data for %s: %s\n",
smb_fname_str_dbg(smb_fname),
nt_errstr(status));
return status;
}
/*
* Remove the type info we got via stat() and use what
* we got from the reparse point.
*/
mode &= ~S_IFMT;
mode |= type;
}
*dst = (struct smb3_file_posix_information) {
.end_of_file = get_file_size_stat(st),
.allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,NULL,st),
@ -40,9 +158,10 @@ void smb3_file_posix_information_init(
.last_access_time = unix_timespec_to_nt_time(st->st_ex_atime),
.last_write_time = unix_timespec_to_nt_time(st->st_ex_mtime),
.change_time = unix_timespec_to_nt_time(st->st_ex_ctime),
.file_attributes = dos_attributes,
.cc.nlinks = st->st_ex_nlink,
.cc.reparse_tag = reparse_tag,
.cc.posix_mode = unix_mode_to_wire(st->st_ex_mode),
.cc.posix_mode = unix_mode_to_wire(mode),
.cc.owner = global_sid_NULL,
.cc.group = global_sid_NULL,
};
@ -53,21 +172,5 @@ void smb3_file_posix_information_init(
if (st->st_ex_gid != (uid_t)-1) {
gid_to_sid(&dst->cc.group, st->st_ex_gid);
}
switch (st->st_ex_mode & S_IFMT) {
case S_IFREG:
dst->file_attributes = dos_attributes;
break;
case S_IFDIR:
dst->file_attributes = dos_attributes | FILE_ATTRIBUTE_DIRECTORY;
break;
default:
/*
* All non-directory or regular files are reported
* as reparse points. Client may or may not be able
* to access these.
*/
dst->file_attributes = FILE_ATTRIBUTE_REPARSE_POINT;
break;
}
return NT_STATUS_OK;
}

View File

@ -372,7 +372,7 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx,
tevent_req_nterror(req, NT_STATUS_INVALID_LEVEL);
return tevent_req_post(req, ev);
}
state->info_level = SMB2_FILE_POSIX_INFORMATION;
state->info_level = FSCC_FILE_POSIX_INFORMATION;
break;
default:
tevent_req_nterror(req, NT_STATUS_INVALID_INFO_CLASS);

View File

@ -1680,7 +1680,7 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
/* SMB2 UNIX Extension. */
case SMB2_FILE_POSIX_INFORMATION:
case FSCC_FILE_POSIX_INFORMATION:
{
struct smb3_file_posix_information info = {};
uint8_t buf[sizeof(info)];
@ -1690,9 +1690,8 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
.fixed_buf_size = true,
};
enum ndr_err_code ndr_err;
uint32_t tag = 0;
DBG_DEBUG("SMB2_FILE_POSIX_INFORMATION\n");
DBG_DEBUG("FSCC_FILE_POSIX_INFORMATION\n");
p+= 4;
SIVAL(p,0,reskey); p+= 4;
@ -1701,21 +1700,12 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
return NT_STATUS_INVALID_LEVEL;
}
if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
status = fsctl_get_reparse_tag(smb_fname->fsp,
&tag);
if (!NT_STATUS_IS_OK(status)) {
DBG_DEBUG("Could not get reparse "
"tag for %s: %s\n",
smb_fname_str_dbg(smb_fname),
nt_errstr(status));
return status;
}
status = smb3_file_posix_information_init(
conn, smb_fname, mode, &info);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
smb3_file_posix_information_init(
conn, &smb_fname->st, tag, mode, &info);
ndr_err = ndr_push_smb3_file_posix_information(
&ndr, NDR_SCALARS|NDR_BUFFERS, &info);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@ -1960,7 +1950,7 @@ static bool fsinfo_unix_valid_level(connection_struct *conn,
{
if (conn_using_smb2(conn->sconn) &&
fsp->fsp_flags.posix_open &&
info_level == SMB2_FS_POSIX_INFORMATION_INTERNAL)
info_level == FSCC_FS_POSIX_INFORMATION)
{
return true;
}
@ -2473,7 +2463,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
#endif
case SMB_QUERY_POSIX_FS_INFO:
case SMB2_FS_POSIX_INFORMATION_INTERNAL:
case FSCC_FS_POSIX_INFORMATION:
{
int rc;
struct vfs_statvfs_struct svfs;
@ -3648,7 +3638,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
/*
* SMB2 UNIX Extensions.
*/
case SMB2_FILE_POSIX_INFORMATION_INTERNAL:
case FSCC_FILE_POSIX_INFORMATION:
{
struct smb3_file_posix_information info = {};
uint8_t buf[sizeof(info)];
@ -3669,8 +3659,11 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
return NT_STATUS_INVALID_LEVEL;
}
smb3_file_posix_information_init(
conn, &smb_fname->st, 0, mode, &info);
status = smb3_file_posix_information_init(
conn, smb_fname, mode, &info);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
ndr_err = ndr_push_smb3_file_posix_information(
&ndr, NDR_SCALARS|NDR_BUFFERS, &info);