mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added patch to fix handling of opening a file with RootDirectory pointing to a file handle.
This commit is contained in:
parent
f5c6731e84
commit
c632b99fb5
@ -39,7 +39,7 @@ Wine. All those differences are also documented on the
|
||||
Included bug fixes and improvements
|
||||
-----------------------------------
|
||||
|
||||
**Bug fixes and features included in the next upcoming release [11]:**
|
||||
**Bug fixes and features included in the next upcoming release [12]:**
|
||||
|
||||
* Add shell32 placeholder icons to match offsets with Windows ([Wine Bug #30185](https://bugs.winehq.org/show_bug.cgi?id=30185))
|
||||
* Add stub for iphlpapi.ConvertInterfaceLuidToGuid ([Wine Bug #38576](https://bugs.winehq.org/show_bug.cgi?id=38576))
|
||||
@ -49,6 +49,7 @@ Included bug fixes and improvements
|
||||
* Assign a drive serial number during prefix creation/update ([Wine Bug #17823](https://bugs.winehq.org/show_bug.cgi?id=17823))
|
||||
* Fix NULL pointer dereference in get_frame_by_name ([Wine Bug #34982](https://bugs.winehq.org/show_bug.cgi?id=34982))
|
||||
* Fix crash in Gothic 1/2 with builtin directmusic caused by wrong return value ([Wine Bug #7425](https://bugs.winehq.org/show_bug.cgi?id=7425))
|
||||
* Fix handling of opening a file with RootDirectory pointing to a file handle
|
||||
* Return fake device type when systemroot is located on virtual disk ([Wine Bug #36546](https://bugs.winehq.org/show_bug.cgi?id=36546))
|
||||
* Support for ws2_32.dll.WSAPoll ([Wine Bug #38601](https://bugs.winehq.org/show_bug.cgi?id=38601))
|
||||
* Use random names when caching very long urls in wininet
|
||||
|
2
debian/changelog
vendored
2
debian/changelog
vendored
@ -13,6 +13,8 @@ wine-staging (1.7.44) UNRELEASED; urgency=low
|
||||
* Added patch to return fake device type when systemroot is located on virtual
|
||||
disk (improves compatibility when wineprefix is on tmpfs).
|
||||
* Added patch to fix NULL pointer dereference in get_frame_by_name.
|
||||
* Added patch to fix handling of opening a file with RootDirectory pointing to
|
||||
a file handle.
|
||||
* Removed patch to reset device state in SysKeyboard*Impl_Acquire (accepted
|
||||
upstream).
|
||||
* Removed patch to avoid creating thread queues for foreign threads in
|
||||
|
@ -210,6 +210,7 @@ patch_enable_all ()
|
||||
enable_server_OpenProcess="$1"
|
||||
enable_server_PeekMessage="$1"
|
||||
enable_server_Realtime_Priority="$1"
|
||||
enable_server_RootDirectory_File="$1"
|
||||
enable_server_Shared_Memory="$1"
|
||||
enable_server_Stored_ACLs="$1"
|
||||
enable_server_Unexpected_Wakeup="$1"
|
||||
@ -694,6 +695,9 @@ patch_enable ()
|
||||
server-Realtime_Priority)
|
||||
enable_server_Realtime_Priority="$2"
|
||||
;;
|
||||
server-RootDirectory_File)
|
||||
enable_server_RootDirectory_File="$2"
|
||||
;;
|
||||
server-Shared_Memory)
|
||||
enable_server_Shared_Memory="$2"
|
||||
;;
|
||||
@ -1682,8 +1686,12 @@ if test "$enable_server_Stored_ACLs" -eq 1; then
|
||||
if test "$enable_server_File_Permissions" -gt 1; then
|
||||
abort "Patchset server-File_Permissions disabled, but server-Stored_ACLs depends on that."
|
||||
fi
|
||||
if test "$enable_server_RootDirectory_File" -gt 1; then
|
||||
abort "Patchset server-RootDirectory_File disabled, but server-Stored_ACLs depends on that."
|
||||
fi
|
||||
enable_ntdll_DOS_Attributes=1
|
||||
enable_server_File_Permissions=1
|
||||
enable_server_RootDirectory_File=1
|
||||
fi
|
||||
|
||||
if test "$enable_nvencodeapi_Video_Encoder" -eq 1; then
|
||||
@ -4552,6 +4560,18 @@ if test "$enable_secur32_ANSI_NTLM_Credentials" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset server-RootDirectory_File
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/tests/file.c, server/fd.c, server/file.c
|
||||
# |
|
||||
if test "$enable_server_RootDirectory_File" -eq 1; then
|
||||
patch_apply server-RootDirectory_File/0001-server-Fix-handling-of-opening-a-file-with-RootDirec.patch
|
||||
(
|
||||
echo '+ { "Sebastian Lackner", "server: Fix handling of opening a file with RootDirectory pointing to a file handle.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset server-Stored_ACLs
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
@ -0,0 +1,153 @@
|
||||
From 5eb09620a17c714c4a2162dd69d4f748f5634859 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 29 May 2015 22:49:24 +0200
|
||||
Subject: server: Fix handling of opening a file with RootDirectory pointing to
|
||||
a file handle.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 13 +++++++++++--
|
||||
server/fd.c | 32 ++++++++++++++++++++++++++------
|
||||
server/file.c | 22 +++++++++++++++++++++-
|
||||
3 files changed, 58 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 2df0edc..1e5b340 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -297,7 +297,7 @@ static void create_file_test(void)
|
||||
|
||||
static void open_file_test(void)
|
||||
{
|
||||
- static const WCHAR fooW[] = {'f','o','o',0};
|
||||
+ static WCHAR fooW[] = {'f','o','o',0};
|
||||
NTSTATUS status;
|
||||
HANDLE dir, root, handle, file;
|
||||
WCHAR path[MAX_PATH], tmpfile[MAX_PATH];
|
||||
@@ -443,13 +443,22 @@ static void open_file_test(void)
|
||||
ok( !status, "open %s failed %x\n", wine_dbgstr_w(nameW.Buffer), status );
|
||||
pRtlFreeUnicodeString( &nameW );
|
||||
|
||||
+ nameW.Length = sizeof(fooW) - sizeof(WCHAR);
|
||||
+ nameW.Buffer = fooW;
|
||||
+ attr.RootDirectory = file;
|
||||
+ attr.ObjectName = &nameW;
|
||||
+ status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
|
||||
+ FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT );
|
||||
+ ok( status == STATUS_OBJECT_PATH_NOT_FOUND,
|
||||
+ "expected STATUS_OBJECT_PATH_NOT_FOUND, got %08x\n", status );
|
||||
+
|
||||
nameW.Length = 0;
|
||||
nameW.Buffer = NULL;
|
||||
attr.RootDirectory = file;
|
||||
attr.ObjectName = &nameW;
|
||||
status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
|
||||
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT );
|
||||
- todo_wine ok( !status, "open %s failed %x\n", wine_dbgstr_w(tmpfile), status );
|
||||
+ ok( !status, "open %s failed %x\n", wine_dbgstr_w(tmpfile), status );
|
||||
|
||||
CloseHandle( file );
|
||||
CloseHandle( root );
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index f0a52ad..2fee65d 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2238,14 +2238,36 @@ DECL_HANDLER(flush)
|
||||
DECL_HANDLER(open_file_object)
|
||||
{
|
||||
struct unicode_str name;
|
||||
- struct directory *root = NULL;
|
||||
+ struct directory *root;
|
||||
struct object *obj, *result;
|
||||
|
||||
get_req_unicode_str( &name );
|
||||
- if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
|
||||
- return;
|
||||
+ if (req->rootdir)
|
||||
+ {
|
||||
+ if ((root = get_directory_obj( current->process, req->rootdir, 0 )))
|
||||
+ {
|
||||
+ obj = open_object_dir( root, &name, req->attributes, NULL );
|
||||
+ release_object( root );
|
||||
+ }
|
||||
+ else if (get_error() == STATUS_OBJECT_TYPE_MISMATCH &&
|
||||
+ (obj = (struct object *)get_file_obj( current->process, req->rootdir, 0 )))
|
||||
+ {
|
||||
+ if (name.len)
|
||||
+ {
|
||||
+ release_object( obj );
|
||||
+ set_error( STATUS_OBJECT_PATH_NOT_FOUND );
|
||||
+ return;
|
||||
+ }
|
||||
+ clear_error();
|
||||
+ }
|
||||
+ else return;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ obj = open_object_dir( NULL, &name, req->attributes, NULL );
|
||||
+ }
|
||||
|
||||
- if ((obj = open_object_dir( root, &name, req->attributes, NULL )))
|
||||
+ if (obj)
|
||||
{
|
||||
if ((result = obj->ops->open_file( obj, req->access, req->sharing, req->options )))
|
||||
{
|
||||
@@ -2254,8 +2276,6 @@ DECL_HANDLER(open_file_object)
|
||||
}
|
||||
release_object( obj );
|
||||
}
|
||||
-
|
||||
- if (root) release_object( root );
|
||||
}
|
||||
|
||||
/* get the Unix name from a file handle */
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 792bbe0..900a17b 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -67,6 +67,8 @@ static void file_dump( struct object *obj, int verbose );
|
||||
static struct fd *file_get_fd( struct object *obj );
|
||||
static struct security_descriptor *file_get_sd( struct object *obj );
|
||||
static int file_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info );
|
||||
+static struct object *file_open_file( struct object *obj, unsigned int access,
|
||||
+ unsigned int sharing, unsigned int options );
|
||||
static void file_destroy( struct object *obj );
|
||||
|
||||
static int file_get_poll_events( struct fd *fd );
|
||||
@@ -88,7 +90,7 @@ static const struct object_ops file_ops =
|
||||
file_get_sd, /* get_sd */
|
||||
file_set_sd, /* set_sd */
|
||||
no_lookup_name, /* lookup_name */
|
||||
- no_open_file, /* open_file */
|
||||
+ file_open_file, /* open_file */
|
||||
fd_close_handle, /* close_handle */
|
||||
file_destroy /* destroy */
|
||||
};
|
||||
@@ -597,6 +599,24 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static struct object *file_open_file( struct object *obj, unsigned int access,
|
||||
+ unsigned int sharing, unsigned int options )
|
||||
+{
|
||||
+ struct file *file = (struct file *)obj;
|
||||
+ struct object *new_file = NULL;
|
||||
+ struct fd *new_fd;
|
||||
+
|
||||
+ assert( obj->ops == &file_ops );
|
||||
+
|
||||
+ if ((new_fd = dup_fd_object( file->fd, access, sharing, options )))
|
||||
+ {
|
||||
+ new_file = create_file_obj( new_fd, access, file->mode );
|
||||
+ release_object( new_fd );
|
||||
+ }
|
||||
+
|
||||
+ return new_file;
|
||||
+}
|
||||
+
|
||||
static void file_destroy( struct object *obj )
|
||||
{
|
||||
struct file *file = (struct file *)obj;
|
||||
--
|
||||
2.4.2
|
||||
|
1
patches/server-RootDirectory_File/definition
Normal file
1
patches/server-RootDirectory_File/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: Fix handling of opening a file with RootDirectory pointing to a file handle
|
@ -1,4 +1,4 @@
|
||||
From 1ea227122c6155c07d254826b03f76d4f95e876d Mon Sep 17 00:00:00 2001
|
||||
From 206f6039e58d89affc810d0f1a2ef2ff956e16d1 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 17 Apr 2014 16:07:46 -0600
|
||||
Subject: server: Unify the storage of security attributes for files and
|
||||
@ -11,10 +11,10 @@ Subject: server: Unify the storage of security attributes for files and
|
||||
3 files changed, 30 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/server/change.c b/server/change.c
|
||||
index 3ac70a4..c2fe428 100644
|
||||
index 11d9b93..b073271 100644
|
||||
--- a/server/change.c
|
||||
+++ b/server/change.c
|
||||
@@ -321,48 +321,15 @@ static int dir_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
@@ -323,48 +323,15 @@ static int dir_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
unsigned int set_info )
|
||||
{
|
||||
struct dir *dir = (struct dir *)obj;
|
||||
@ -70,10 +70,10 @@ index 3ac70a4..c2fe428 100644
|
||||
|
||||
static struct change_record *get_first_change_record( struct dir *dir )
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index aa5ff01..fed2e45 100644
|
||||
index 1f9aa1f..b0be2ec 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -544,18 +544,13 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
|
||||
@@ -549,18 +549,13 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
|
||||
return new_mode;
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ index aa5ff01..fed2e45 100644
|
||||
|
||||
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1;
|
||||
|
||||
@@ -582,10 +577,10 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
|
||||
@@ -587,10 +582,10 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
|
||||
if (set_info & DACL_SECURITY_INFORMATION)
|
||||
{
|
||||
/* keep the bits that we don't map to access rights in the ACL */
|
||||
@ -110,8 +110,8 @@ index aa5ff01..fed2e45 100644
|
||||
{
|
||||
file_set_error();
|
||||
return 0;
|
||||
@@ -594,6 +589,21 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd
|
||||
return 1;
|
||||
@@ -617,6 +612,21 @@ static struct object *file_open_file( struct object *obj, unsigned int access,
|
||||
return new_file;
|
||||
}
|
||||
|
||||
+static int file_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
@ -133,10 +133,10 @@ index aa5ff01..fed2e45 100644
|
||||
{
|
||||
struct file *file = (struct file *)obj;
|
||||
diff --git a/server/file.h b/server/file.h
|
||||
index 85e4257..d1365b0 100644
|
||||
index 460656f..28f91f4 100644
|
||||
--- a/server/file.h
|
||||
+++ b/server/file.h
|
||||
@@ -124,6 +124,8 @@ extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access,
|
||||
@@ -129,6 +129,8 @@ extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access,
|
||||
extern void file_set_error(void);
|
||||
extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group );
|
||||
extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner );
|
||||
@ -146,5 +146,5 @@ index 85e4257..d1365b0 100644
|
||||
/* file mapping functions */
|
||||
|
||||
--
|
||||
2.3.5
|
||||
2.4.2
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 7a54a4e7c856d5df1075b55eaa823c9c1826fd0b Mon Sep 17 00:00:00 2001
|
||||
From 5716cf425f78feb8d4f439488a36b4a3339c301e Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Mon, 30 Mar 2015 12:50:21 +0200
|
||||
Subject: server: Temporarily store the full security descriptor for file
|
||||
@ -12,7 +12,7 @@ Subject: server: Temporarily store the full security descriptor for file
|
||||
4 files changed, 74 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
|
||||
index a0532f6..f7ae089 100644
|
||||
index 40cf23c..57adc4e 100644
|
||||
--- a/dlls/advapi32/tests/security.c
|
||||
+++ b/dlls/advapi32/tests/security.c
|
||||
@@ -3311,7 +3311,6 @@ static void test_CreateDirectoryA(void)
|
||||
@ -39,7 +39,7 @@ index a0532f6..f7ae089 100644
|
||||
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
|
||||
acl_size.AceCount);
|
||||
LocalFree(pSD);
|
||||
@@ -4501,22 +4498,22 @@ static void test_GetSecurityInfo(void)
|
||||
@@ -4508,22 +4505,22 @@ static void test_GetSecurityInfo(void)
|
||||
bret = pGetAce(pDacl, 0, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Current User ACE.\n");
|
||||
bret = EqualSid(&ace->SidStart, user_sid);
|
||||
@ -69,10 +69,10 @@ index a0532f6..f7ae089 100644
|
||||
LocalFree(pSD);
|
||||
CloseHandle(obj);
|
||||
diff --git a/server/change.c b/server/change.c
|
||||
index 29a48b3..87b45f8 100644
|
||||
index b334fd1..2e98f5c 100644
|
||||
--- a/server/change.c
|
||||
+++ b/server/change.c
|
||||
@@ -1020,7 +1020,8 @@ static int dir_add_to_existing_notify( struct dir *dir )
|
||||
@@ -1022,7 +1022,8 @@ static int dir_add_to_existing_notify( struct dir *dir )
|
||||
|
||||
#endif /* USE_INOTIFY */
|
||||
|
||||
@ -82,7 +82,7 @@ index 29a48b3..87b45f8 100644
|
||||
{
|
||||
struct dir *dir;
|
||||
|
||||
@@ -1039,6 +1040,11 @@ struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode )
|
||||
@@ -1041,6 +1042,11 @@ struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode )
|
||||
dir->uid = ~(uid_t)0;
|
||||
set_fd_user( fd, &dir_fd_ops, &dir->obj );
|
||||
|
||||
@ -95,10 +95,10 @@ index 29a48b3..87b45f8 100644
|
||||
|
||||
return &dir->obj;
|
||||
diff --git a/server/file.c b/server/file.c
|
||||
index 58906c0..1b16526 100644
|
||||
index 729ef87..1daef88 100644
|
||||
--- a/server/file.c
|
||||
+++ b/server/file.c
|
||||
@@ -168,7 +168,8 @@ struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigne
|
||||
@@ -172,7 +172,8 @@ struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigne
|
||||
return file;
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ index 58906c0..1b16526 100644
|
||||
{
|
||||
struct file *file = alloc_object( &file_ops );
|
||||
|
||||
@@ -179,6 +180,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
@@ -183,6 +184,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
|
||||
file->fd = fd;
|
||||
grab_object( fd );
|
||||
set_fd_user( fd, &file_fd_ops, &file->obj );
|
||||
@ -121,7 +121,7 @@ index 58906c0..1b16526 100644
|
||||
return &file->obj;
|
||||
}
|
||||
|
||||
@@ -245,11 +252,11 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
@@ -249,11 +256,11 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
|
||||
if (!fd) goto done;
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
@ -135,7 +135,7 @@ index 58906c0..1b16526 100644
|
||||
|
||||
release_object( fd );
|
||||
|
||||
@@ -557,46 +564,66 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
|
||||
@@ -562,46 +569,66 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
|
||||
int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid,
|
||||
const struct security_descriptor *sd, unsigned int set_info )
|
||||
{
|
||||
@ -226,8 +226,8 @@ index 58906c0..1b16526 100644
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int file_set_sd( struct object *obj, const struct security_descriptor *sd,
|
||||
@@ -709,7 +736,10 @@ DECL_HANDLER(create_file)
|
||||
static struct object *file_open_file( struct object *obj, unsigned int access,
|
||||
@@ -732,7 +759,10 @@ DECL_HANDLER(create_file)
|
||||
if ((file = create_file( root_fd, name, name_len, req->access, req->sharing,
|
||||
req->create, req->options, req->attrs, sd )))
|
||||
{
|
||||
@ -240,10 +240,10 @@ index 58906c0..1b16526 100644
|
||||
}
|
||||
if (root_fd) release_object( root_fd );
|
||||
diff --git a/server/file.h b/server/file.h
|
||||
index c866312..16883b2 100644
|
||||
index 740a36f..5619bba 100644
|
||||
--- a/server/file.h
|
||||
+++ b/server/file.h
|
||||
@@ -142,7 +142,8 @@ extern int get_page_size(void);
|
||||
@@ -154,7 +154,8 @@ extern struct device *create_unix_device( struct directory *root, const struct u
|
||||
|
||||
extern void do_change_notify( int unix_fd );
|
||||
extern void sigio_callback(void);
|
||||
@ -254,5 +254,5 @@ index c866312..16883b2 100644
|
||||
|
||||
/* completion */
|
||||
--
|
||||
2.3.5
|
||||
2.4.2
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
Depends: ntdll-DOS_Attributes
|
||||
Depends: server-File_Permissions
|
||||
Depends: server-RootDirectory_File
|
||||
Fixes: [33576] Support for stored file ACLs
|
||||
|
Loading…
Reference in New Issue
Block a user