Accepting request 676044 from network:samba:STABLE
OBS-URL: https://build.opensuse.org/request/show/676044 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/cifs-utils?expand=0&rev=55
This commit is contained in:
commit
b8fa744982
268
allow-dns-resolver-key-to-expire.patch
Normal file
268
allow-dns-resolver-key-to-expire.patch
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
From paulo@paulo.ac Wed Feb 13 18:09:41 2019
|
||||||
|
Return-path: <linux-cifs-owner@vger.kernel.org>
|
||||||
|
Received: from prv1-mx.provo.novell.com (novprvlin0515.provo.novell.com [130.57.1.105])
|
||||||
|
by prv-mh.provo.novell.com with ESMTP (NOT encrypted); Wed, 13 Feb 2019 11:09:56 -0700
|
||||||
|
Received: from vger.kernel.org (209.132.180.67) by prv1-mx.provo.novell.com (130.57.1.11) GWAVA SMTP; Wed, 13 Feb 2019 11:09:57 -0700
|
||||||
|
X-Spam_ID: str=0001.0A020211.5C645D75.005D,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0
|
||||||
|
X-GWAVADAT: <keymat><rkey>zFPcY7v2brlPt6Q2</rkey><gkey>e5327cab1501d80247f45f4235d8ab62d9cebc212966054348ffdffbdcecc4b3</gkey><objectid>17boib3.17boib3.v6</objectid></keymat>
|
||||||
|
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
||||||
|
id S1729522AbfBMSJ4 (ORCPT <rfc822;dmulder@suse.com> + 3 others);
|
||||||
|
Wed, 13 Feb 2019 13:09:56 -0500
|
||||||
|
Received: from mail.paulo.ac ([18.228.144.36]:36484 "EHLO mail.paulo.ac"
|
||||||
|
rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
|
||||||
|
id S1727937AbfBMSJz (ORCPT <rfc822;linux-cifs@vger.kernel.org>);
|
||||||
|
Wed, 13 Feb 2019 13:09:55 -0500
|
||||||
|
Received: from localhost (localhost [127.0.0.1])
|
||||||
|
by mail.paulo.ac (Postfix) with ESMTP id 908B04823B16;
|
||||||
|
Wed, 13 Feb 2019 18:09:52 +0000 (UTC)
|
||||||
|
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=paulo.ac; s=default;
|
||||||
|
t=1550081392; bh=NPHMWzhC+dOx1uqYM9k6+umJOPTfdQQb4DDuwxCPykY=;
|
||||||
|
h=From:To:Cc:Subject:Date;
|
||||||
|
b=T/4Gj7VIMqZKmdsNgp0GA1d/4g7rZD8wHngdPprFv5GJ3kwcM0HAiFs9IY7sqln2m
|
||||||
|
+zAQ9B5qbEoeJif9o/LeR7ED+kqAZyn+uGitgiE7DcMJ5wzvGIDZyl/KAGQn/35Auf
|
||||||
|
BNdDIwgVMyv0Iba6DiPlLSIXP9QBxBlXHGDD90fE=
|
||||||
|
Received: from mail.paulo.ac ([127.0.0.1])
|
||||||
|
by localhost (ip-172-31-5-70.sa-east-1.compute.internal [127.0.0.1]) (amavisd-new, port 10024)
|
||||||
|
with ESMTP id ztemnOMlOHdf; Wed, 13 Feb 2019 18:09:51 +0000 (UTC)
|
||||||
|
Received: from localhost.localdomain (unknown [186.215.53.127])
|
||||||
|
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
|
||||||
|
(No client certificate requested)
|
||||||
|
by mail.paulo.ac (Postfix) with ESMTPSA id CAFF84822E3F;
|
||||||
|
Wed, 13 Feb 2019 18:09:50 +0000 (UTC)
|
||||||
|
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=paulo.ac; s=default;
|
||||||
|
t=1550081391; bh=NPHMWzhC+dOx1uqYM9k6+umJOPTfdQQb4DDuwxCPykY=;
|
||||||
|
h=From:To:Cc:Subject:Date;
|
||||||
|
b=iyVAaOItT0Qa5SuPc9LRAoN1qb8VHw5hZNzhOF6NOB178UgZYt2Tt9pzR9/0UbhUF
|
||||||
|
GeJP0gK64HWvGmbDz8zRhrVgnZpGgAXfaPa20AuGm3WlrtZpb3Z2s/krSAI2I1tQfx
|
||||||
|
82wY8IeZOD9F+709ZZlwlkGHMWiDLaiRH7xTJWIU=
|
||||||
|
From: Paulo Alcantara <paulo@paulo.ac>
|
||||||
|
To: linux-cifs@vger.kernel.org
|
||||||
|
Cc: smfrench@gmail.com, aaptel@suse.com, piastryyy@gmail.com,
|
||||||
|
Paulo Alcantara <paulo@paulo.ac>,
|
||||||
|
Paulo Alcantara <palcantara@suse.de>
|
||||||
|
Subject: [PATCH] cifs: Allow DNS resolver key to expire
|
||||||
|
Date: Wed, 13 Feb 2019 16:09:41 -0200
|
||||||
|
Message-Id: <20190213180941.2587-1-paulo@paulo.ac>
|
||||||
|
X-Mailer: git-send-email 2.20.1
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
Sender: linux-cifs-owner@vger.kernel.org
|
||||||
|
Precedence: bulk
|
||||||
|
List-ID: <linux-cifs.vger.kernel.org>
|
||||||
|
X-Mailing-List: linux-cifs@vger.kernel.org
|
||||||
|
|
||||||
|
This patch introduces a new '--expire' option that allows the user to
|
||||||
|
set a timeout value for the dns resolver key -- which is typically
|
||||||
|
useful for hostnames that may get their ip addresses changed under
|
||||||
|
long running mounts.
|
||||||
|
|
||||||
|
The default timeout value is set to 10 minutes.
|
||||||
|
|
||||||
|
Signed-off-by: Paulo Alcantara <palcantara@suse.de>
|
||||||
|
---
|
||||||
|
cifs.upcall.c | 88 +++++++++++++++++++++++++++++++++-------------
|
||||||
|
cifs.upcall.rst.in | 5 ++-
|
||||||
|
2 files changed, 67 insertions(+), 26 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/cifs.upcall.c b/cifs.upcall.c
|
||||||
|
index 89563fd42adc..c92ee62f6764 100644
|
||||||
|
--- a/cifs.upcall.c
|
||||||
|
+++ b/cifs.upcall.c
|
||||||
|
@@ -63,6 +63,8 @@
|
||||||
|
static krb5_context context;
|
||||||
|
static const char *prog = "cifs.upcall";
|
||||||
|
|
||||||
|
+#define DNS_RESOLVER_DEFAULT_TIMEOUT 600 /* 10 minutes */
|
||||||
|
+
|
||||||
|
typedef enum _sectype {
|
||||||
|
NONE = 0,
|
||||||
|
KRB5,
|
||||||
|
@@ -749,19 +751,48 @@ decode_key_description(const char *desc, struct decoded_args *arg)
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int cifs_resolver(const key_serial_t key, const char *key_descr)
|
||||||
|
+static int setup_key(const key_serial_t key, const void *data, size_t datalen)
|
||||||
|
+{
|
||||||
|
+ int rc;
|
||||||
|
+
|
||||||
|
+ rc = keyctl_instantiate(key, data, datalen, 0);
|
||||||
|
+ if (rc) {
|
||||||
|
+ switch (errno) {
|
||||||
|
+ case ENOMEM:
|
||||||
|
+ case EDQUOT:
|
||||||
|
+ rc = keyctl_clear(key);
|
||||||
|
+ if (rc) {
|
||||||
|
+ syslog(LOG_ERR, "%s: keyctl_clear: %s",
|
||||||
|
+ __func__, strerror(errno));
|
||||||
|
+ return rc;
|
||||||
|
+ }
|
||||||
|
+ rc = keyctl_instantiate(key, data, datalen, 0);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ ;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (rc) {
|
||||||
|
+ syslog(LOG_ERR, "%s: keyctl_instantiate: %s",
|
||||||
|
+ __func__, strerror(errno));
|
||||||
|
+ }
|
||||||
|
+ return rc;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int cifs_resolver(const key_serial_t key, const char *key_descr,
|
||||||
|
+ const char *key_buf, unsigned expire_time)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
struct addrinfo *addr;
|
||||||
|
char ip[INET6_ADDRSTRLEN];
|
||||||
|
void *p;
|
||||||
|
- const char *keyend = key_descr;
|
||||||
|
+ const char *keyend = key_buf;
|
||||||
|
/* skip next 4 ';' delimiters to get to description */
|
||||||
|
for (c = 1; c <= 4; c++) {
|
||||||
|
keyend = index(keyend + 1, ';');
|
||||||
|
if (!keyend) {
|
||||||
|
syslog(LOG_ERR, "invalid key description: %s",
|
||||||
|
- key_descr);
|
||||||
|
+ key_buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -787,15 +818,21 @@ static int cifs_resolver(const key_serial_t key, const char *key_descr)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* setup key */
|
||||||
|
- c = keyctl_instantiate(key, ip, strlen(ip) + 1, 0);
|
||||||
|
- if (c == -1) {
|
||||||
|
- syslog(LOG_ERR, "%s: keyctl_instantiate: %s", __func__,
|
||||||
|
- strerror(errno));
|
||||||
|
- freeaddrinfo(addr);
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
+ /* needed for keyctl_set_timeout() */
|
||||||
|
+ request_key("keyring", key_descr, NULL, KEY_SPEC_THREAD_KEYRING);
|
||||||
|
|
||||||
|
+ c = setup_key(key, ip, strlen(ip) + 1);
|
||||||
|
+ if (c) {
|
||||||
|
+ freeaddrinfo(addr);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ c = keyctl_set_timeout(key, expire_time);
|
||||||
|
+ if (c) {
|
||||||
|
+ syslog(LOG_ERR, "%s: keyctl_set_timeout: %s", __func__,
|
||||||
|
+ strerror(errno));
|
||||||
|
+ freeaddrinfo(addr);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
freeaddrinfo(addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -864,7 +901,7 @@ lowercase_string(char *c)
|
||||||
|
|
||||||
|
static void usage(void)
|
||||||
|
{
|
||||||
|
- fprintf(stderr, "Usage: %s [ -K /path/to/keytab] [-k /path/to/krb5.conf] [-E] [-t] [-v] [-l] key_serial\n", prog);
|
||||||
|
+ fprintf(stderr, "Usage: %s [ -K /path/to/keytab] [-k /path/to/krb5.conf] [-E] [-t] [-v] [-l] [-e nsecs] key_serial\n", prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct option long_options[] = {
|
||||||
|
@@ -874,6 +911,7 @@ static const struct option long_options[] = {
|
||||||
|
{"trust-dns", 0, NULL, 't'},
|
||||||
|
{"keytab", 1, NULL, 'K'},
|
||||||
|
{"version", 0, NULL, 'v'},
|
||||||
|
+ {"expire", 1, NULL, 'e'},
|
||||||
|
{NULL, 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -897,13 +935,15 @@ int main(const int argc, char *const argv[])
|
||||||
|
char *env_cachename = NULL;
|
||||||
|
krb5_ccache ccache = NULL;
|
||||||
|
struct passwd *pw;
|
||||||
|
+ unsigned expire_time = DNS_RESOLVER_DEFAULT_TIMEOUT;
|
||||||
|
+ const char *key_descr = NULL;
|
||||||
|
|
||||||
|
hostbuf[0] = '\0';
|
||||||
|
memset(&arg, 0, sizeof(arg));
|
||||||
|
|
||||||
|
openlog(prog, 0, LOG_DAEMON);
|
||||||
|
|
||||||
|
- while ((c = getopt_long(argc, argv, "cEk:K:ltv", long_options, NULL)) != -1) {
|
||||||
|
+ while ((c = getopt_long(argc, argv, "cEk:K:ltve:", long_options, NULL)) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'c':
|
||||||
|
/* legacy option -- skip it */
|
||||||
|
@@ -931,6 +971,9 @@ int main(const int argc, char *const argv[])
|
||||||
|
rc = 0;
|
||||||
|
printf("version: %s\n", VERSION);
|
||||||
|
goto out;
|
||||||
|
+ case 'e':
|
||||||
|
+ expire_time = strtoul(optarg, NULL, 10);
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
syslog(LOG_ERR, "unknown option: %c", c);
|
||||||
|
goto out;
|
||||||
|
@@ -965,9 +1008,12 @@ int main(const int argc, char *const argv[])
|
||||||
|
|
||||||
|
syslog(LOG_DEBUG, "key description: %s", buf);
|
||||||
|
|
||||||
|
- if ((strncmp(buf, "cifs.resolver", sizeof("cifs.resolver") - 1) == 0) ||
|
||||||
|
- (strncmp(buf, "dns_resolver", sizeof("dns_resolver") - 1) == 0)) {
|
||||||
|
- rc = cifs_resolver(key, buf);
|
||||||
|
+ if (strncmp(buf, "cifs.resolver", sizeof("cifs.resolver") - 1) == 0)
|
||||||
|
+ key_descr = ".cifs.resolver";
|
||||||
|
+ else if (strncmp(buf, "dns_resolver", sizeof("dns_resolver") - 1) == 0)
|
||||||
|
+ key_descr = ".dns_resolver";
|
||||||
|
+ if (key_descr) {
|
||||||
|
+ rc = cifs_resolver(key, key_descr, buf, expire_time);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1193,16 +1239,8 @@ retry_new_hostname:
|
||||||
|
memcpy(&(keydata->data) + keydata->sesskey_len,
|
||||||
|
secblob.data, secblob.length);
|
||||||
|
|
||||||
|
- /* setup key */
|
||||||
|
- rc = keyctl_instantiate(key, keydata, datalen, 0);
|
||||||
|
- if (rc == -1) {
|
||||||
|
- syslog(LOG_ERR, "keyctl_instantiate: %s", strerror(errno));
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
+ rc = setup_key(key, keydata, datalen);
|
||||||
|
|
||||||
|
- /* BB: maybe we need use timeout for key: for example no more then
|
||||||
|
- * ticket lifietime? */
|
||||||
|
- /* keyctl_set_timeout( key, 60); */
|
||||||
|
out:
|
||||||
|
/*
|
||||||
|
* on error, negatively instantiate the key ourselves so that we can
|
||||||
|
diff --git a/cifs.upcall.rst.in b/cifs.upcall.rst.in
|
||||||
|
index 1b8df3f31d94..08ce324fc5f6 100644
|
||||||
|
--- a/cifs.upcall.rst.in
|
||||||
|
+++ b/cifs.upcall.rst.in
|
||||||
|
@@ -13,7 +13,7 @@ SYNOPSIS
|
||||||
|
|
||||||
|
cifs.upcall [--trust-dns|-t] [--version|-v] [--legacy-uid|-l]
|
||||||
|
[--krb5conf=/path/to/krb5.conf|-k /path/to/krb5.conf]
|
||||||
|
- [--keytab=/path/to/keytab|-K /path/to/keytab] {keyid}
|
||||||
|
+ [--keytab=/path/to/keytab|-K /path/to/keytab] [--expire|-e nsecs] {keyid}
|
||||||
|
|
||||||
|
***********
|
||||||
|
DESCRIPTION
|
||||||
|
@@ -85,6 +85,9 @@ OPTIONS
|
||||||
|
user. Set this option if you want cifs.upcall to use the older uid=
|
||||||
|
parameter instead of the creduid= parameter.
|
||||||
|
|
||||||
|
+--expire|-e
|
||||||
|
+ Override default timeout value (600 seconds) for ``dns_resolver`` key.
|
||||||
|
+
|
||||||
|
--version|-v
|
||||||
|
Print version number and exit.
|
||||||
|
|
||||||
|
--
|
||||||
|
2.20.1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,3 +1,23 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Feb 14 11:27:09 UTC 2019 - aaptel@suse.com
|
||||||
|
|
||||||
|
- Allow cached DNS entry to expire
|
||||||
|
* add allow-dns-resolver-key-to-expire.patch
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Feb 12 17:34:00 UTC 2019 - aaptel@suse.com
|
||||||
|
|
||||||
|
- Document new SMB2.1+ defaults
|
||||||
|
* be more verbose on mount errors, especially with EHOSTDOWN which
|
||||||
|
is often returned on SMB version issues.
|
||||||
|
* add suse-document-new-vers-default-SMB2.1.patch
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Feb 11 08:33:10 UTC 2019 - dmulder@suse.com
|
||||||
|
|
||||||
|
- Fix python dependency stalemate by requiring python3 version of
|
||||||
|
samba-libs.
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Mon Sep 10 12:29:37 UTC 2018 - aaptel@suse.com
|
Mon Sep 10 12:29:37 UTC 2018 - aaptel@suse.com
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package cifs-utils
|
# spec file for package cifs-utils
|
||||||
#
|
#
|
||||||
# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
|
# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
|
||||||
#
|
#
|
||||||
# All modifications and additions to the file contributed by third parties
|
# All modifications and additions to the file contributed by third parties
|
||||||
# remain the property of their copyright owners, unless otherwise agreed
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
@ -42,6 +42,8 @@ Patch6: 0007-checkopts-report-duplicated-options-in-man-page.patch
|
|||||||
Patch7: 0008-mount.cifs.rst-more-cleanups.patch
|
Patch7: 0008-mount.cifs.rst-more-cleanups.patch
|
||||||
Patch8: 0009-mount.cifs.rst-document-vers-3-mount-option.patch
|
Patch8: 0009-mount.cifs.rst-document-vers-3-mount-option.patch
|
||||||
Patch9: 0010-mount.cifs.rst-document-vers-3.02-mount-option.patch
|
Patch9: 0010-mount.cifs.rst-document-vers-3.02-mount-option.patch
|
||||||
|
Patch10: suse-document-new-vers-default-SMB2.1.patch
|
||||||
|
Patch11: allow-dns-resolver-key-to-expire.patch
|
||||||
|
|
||||||
# cifs-utils 6.8 switched to python for man page generation
|
# cifs-utils 6.8 switched to python for man page generation
|
||||||
# we need to require either py2 or py3 package
|
# we need to require either py2 or py3 package
|
||||||
@ -83,6 +85,7 @@ BuildRequires: fdupes
|
|||||||
BuildRequires: libwbclient-devel
|
BuildRequires: libwbclient-devel
|
||||||
BuildRequires: pam-devel
|
BuildRequires: pam-devel
|
||||||
BuildRequires: pkg-config
|
BuildRequires: pkg-config
|
||||||
|
BuildRequires: samba-libs-python3
|
||||||
Requires: keyutils
|
Requires: keyutils
|
||||||
%if ! %{defined _rundir}
|
%if ! %{defined _rundir}
|
||||||
%define _rundir %{_localstatedir}/run
|
%define _rundir %{_localstatedir}/run
|
||||||
@ -128,6 +131,8 @@ cp -a ${RPM_SOURCE_DIR}/README.cifstab.migration .
|
|||||||
%patch7 -p1
|
%patch7 -p1
|
||||||
%patch8 -p1
|
%patch8 -p1
|
||||||
%patch9 -p1
|
%patch9 -p1
|
||||||
|
%patch10 -p1
|
||||||
|
%patch11 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
export CFLAGS="%{optflags} -D_GNU_SOURCE -fpie"
|
export CFLAGS="%{optflags} -D_GNU_SOURCE -fpie"
|
||||||
|
37
suse-document-new-vers-default-SMB2.1.patch
Normal file
37
suse-document-new-vers-default-SMB2.1.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
Index: cifs-utils-6.8/mount.cifs.c
|
||||||
|
===================================================================
|
||||||
|
--- cifs-utils-6.8.orig/mount.cifs.c
|
||||||
|
+++ cifs-utils-6.8/mount.cifs.c
|
||||||
|
@@ -2099,6 +2099,10 @@ mount_retry:
|
||||||
|
switch (errno) {
|
||||||
|
case ECONNREFUSED:
|
||||||
|
case EHOSTUNREACH:
|
||||||
|
+ if (currentaddress) {
|
||||||
|
+ fprintf(stderr, "mount error(%d): could not connect to %s",
|
||||||
|
+ errno, currentaddress);
|
||||||
|
+ }
|
||||||
|
currentaddress = nextaddress;
|
||||||
|
if (currentaddress) {
|
||||||
|
nextaddress = strchr(currentaddress, ',');
|
||||||
|
@@ -2110,6 +2114,12 @@ mount_retry:
|
||||||
|
fprintf(stderr,
|
||||||
|
"mount error: %s filesystem not supported by the system\n", cifs_fstype);
|
||||||
|
break;
|
||||||
|
+ case EHOSTDOWN:
|
||||||
|
+ fprintf(stderr,
|
||||||
|
+ "mount error: Server abruptly closed the connection.\n"
|
||||||
|
+ "This can happen if the server does not support the SMB version you are trying to use.\n"
|
||||||
|
+ "The default SMB version recently changed from SMB1 to SMB2.1 and above. Try mounting with vers=1.0.\n");
|
||||||
|
+ break;
|
||||||
|
case ENXIO:
|
||||||
|
if (!already_uppercased &&
|
||||||
|
uppercase_string(parsed_info->host) &&
|
||||||
|
@@ -2126,7 +2136,7 @@ mount_retry:
|
||||||
|
strerror(errno));
|
||||||
|
fprintf(stderr,
|
||||||
|
"Refer to the %s(8) manual page (e.g. man "
|
||||||
|
- "%s)\n", thisprogram, thisprogram);
|
||||||
|
+ "%s) and kernel log messages (dmesg)\n", thisprogram, thisprogram);
|
||||||
|
rc = EX_FAIL;
|
||||||
|
goto mount_exit;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user