forked from pool/libtirpc
Accepting request 345009 from home:kukuk:NSL
- Update to libtirpc-1.0.1 - new major soname - Adjust auth code to match other RPC implementations - Implement more gss auth stuff - use poll() instead of select() in svc_run() - Add more sunrpc compat functions - Sync compat headers with real functions - Drop 005-missing-symvers.patch (upstream) - Drop 006-memleak1.patch (upstream) - Drop 007-memleak2.patch (upstream) - Drop 008-fix-undef-ref.patch (upstream) - Drop 009-authdes_pk_create.patch (upstream) - Drop 010-xdr_sizeof.patch (upstream) - Drop 011-authdes_create.patch (upstream) - Drop 012-xp_sock.patch (upstream) - Drop 099-poll.patch (upstream) - Add 005-libtirpc-1.0.2-rc1.patch (fixes deadlock) - Update 099-poll.patch with newest version send upstream. - Add 099-poll.patch: change svc_run from select() to poll(). OBS-URL: https://build.opensuse.org/request/show/345009 OBS-URL: https://build.opensuse.org/package/show/Base:System/libtirpc?expand=0&rev=53
This commit is contained in:
parent
25987c29d1
commit
619f82ada1
@ -3,7 +3,7 @@ index 290c635..a6a202e 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1,5 +1,4 @@
|
||||
AC_INIT(libtirpc, 0.3.2)
|
||||
AC_INIT(libtirpc, 1.0.1)
|
||||
-AM_INIT_AUTOMAKE([silent-rules])
|
||||
+AM_INIT_AUTOMAKE
|
||||
-AM_SILENT_RULES([yes])
|
||||
|
365
005-libtirpc-1.0.2-rc1.patch
Normal file
365
005-libtirpc-1.0.2-rc1.patch
Normal file
@ -0,0 +1,365 @@
|
||||
diff --git a/src/svc.c b/src/svc.c
|
||||
index 9c41445..b59467b 100644
|
||||
--- a/src/svc.c
|
||||
+++ b/src/svc.c
|
||||
@@ -99,7 +99,7 @@ xprt_register (xprt)
|
||||
{
|
||||
__svc_xports = (SVCXPRT **) calloc (_rpc_dtablesize(), sizeof (SVCXPRT *));
|
||||
if (__svc_xports == NULL)
|
||||
- return;
|
||||
+ goto unlock;
|
||||
}
|
||||
if (sock < _rpc_dtablesize())
|
||||
{
|
||||
@@ -120,14 +120,14 @@ xprt_register (xprt)
|
||||
svc_pollfd[i].fd = sock;
|
||||
svc_pollfd[i].events = (POLLIN | POLLPRI |
|
||||
POLLRDNORM | POLLRDBAND);
|
||||
- return;
|
||||
+ goto unlock;
|
||||
}
|
||||
|
||||
new_svc_pollfd = (struct pollfd *) realloc (svc_pollfd,
|
||||
sizeof (struct pollfd)
|
||||
* (svc_max_pollfd + 1));
|
||||
if (new_svc_pollfd == NULL) /* Out of memory */
|
||||
- return;
|
||||
+ goto unlock;
|
||||
svc_pollfd = new_svc_pollfd;
|
||||
++svc_max_pollfd;
|
||||
|
||||
@@ -135,6 +135,7 @@ xprt_register (xprt)
|
||||
svc_pollfd[svc_max_pollfd - 1].events = (POLLIN | POLLPRI |
|
||||
POLLRDNORM | POLLRDBAND);
|
||||
}
|
||||
+unlock:
|
||||
rwlock_unlock (&svc_fd_lock);
|
||||
}
|
||||
|
||||
diff --git a/src/svc_auth_gss.c b/src/svc_auth_gss.c
|
||||
index b6aa407..bece46a 100644
|
||||
--- a/src/svc_auth_gss.c
|
||||
+++ b/src/svc_auth_gss.c
|
||||
@@ -129,6 +129,8 @@ struct svc_rpc_gss_data {
|
||||
((struct svc_rpc_gss_data *)(auth)->svc_ah_private)
|
||||
|
||||
/* Global server credentials. */
|
||||
+static u_int _svcauth_req_time = 0;
|
||||
+static gss_OID_set_desc _svcauth_oid_set = {1, GSS_C_NULL_OID };
|
||||
static gss_cred_id_t _svcauth_gss_creds;
|
||||
static gss_name_t _svcauth_gss_name = GSS_C_NO_NAME;
|
||||
static char * _svcauth_svc_name = NULL;
|
||||
@@ -167,6 +169,7 @@ svcauth_gss_import_name(char *service)
|
||||
gss_name_t name;
|
||||
gss_buffer_desc namebuf;
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
+ bool_t result;
|
||||
|
||||
gss_log_debug("in svcauth_gss_import_name()");
|
||||
|
||||
@@ -181,22 +184,21 @@ svcauth_gss_import_name(char *service)
|
||||
maj_stat, min_stat);
|
||||
return (FALSE);
|
||||
}
|
||||
- if (svcauth_gss_set_svc_name(name) != TRUE) {
|
||||
- gss_release_name(&min_stat, &name);
|
||||
- return (FALSE);
|
||||
- }
|
||||
- return (TRUE);
|
||||
+ result = svcauth_gss_set_svc_name(name);
|
||||
+ gss_release_name(&min_stat, &name);
|
||||
+ return result;
|
||||
}
|
||||
|
||||
static bool_t
|
||||
-svcauth_gss_acquire_cred(u_int req_time, gss_OID_set_desc *oid_set)
|
||||
+svcauth_gss_acquire_cred(void)
|
||||
{
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
|
||||
gss_log_debug("in svcauth_gss_acquire_cred()");
|
||||
|
||||
- maj_stat = gss_acquire_cred(&min_stat, _svcauth_gss_name, req_time,
|
||||
- oid_set, GSS_C_ACCEPT,
|
||||
+ maj_stat = gss_acquire_cred(&min_stat, _svcauth_gss_name,
|
||||
+ _svcauth_req_time, &_svcauth_oid_set,
|
||||
+ GSS_C_ACCEPT,
|
||||
&_svcauth_gss_creds, NULL, NULL);
|
||||
|
||||
if (maj_stat != GSS_S_COMPLETE) {
|
||||
@@ -300,6 +302,8 @@ svcauth_gss_accept_sec_context(struct svc_req *rqst,
|
||||
NULL,
|
||||
&gd->deleg);
|
||||
|
||||
+ xdr_free((xdrproc_t)xdr_rpc_gss_init_args, (caddr_t)&recv_tok);
|
||||
+
|
||||
if (gr->gr_major != GSS_S_COMPLETE &&
|
||||
gr->gr_major != GSS_S_CONTINUE_NEEDED) {
|
||||
gss_log_status("svcauth_gss_accept_sec_context: accept_sec_context",
|
||||
@@ -352,8 +356,11 @@ svcauth_gss_accept_sec_context(struct svc_req *rqst,
|
||||
return (FALSE);
|
||||
|
||||
rqst->rq_xprt->xp_verf.oa_flavor = RPCSEC_GSS;
|
||||
- rqst->rq_xprt->xp_verf.oa_base = checksum.value;
|
||||
+ memcpy(rqst->rq_xprt->xp_verf.oa_base, checksum.value,
|
||||
+ checksum.length);
|
||||
rqst->rq_xprt->xp_verf.oa_length = checksum.length;
|
||||
+
|
||||
+ gss_release_buffer(&min_stat, &checksum);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
@@ -435,10 +442,13 @@ svcauth_gss_nextverf(struct svc_req *rqst, u_int num)
|
||||
maj_stat, min_stat);
|
||||
return (FALSE);
|
||||
}
|
||||
+
|
||||
rqst->rq_xprt->xp_verf.oa_flavor = RPCSEC_GSS;
|
||||
- rqst->rq_xprt->xp_verf.oa_base = (caddr_t)checksum.value;
|
||||
+ memcpy(rqst->rq_xprt->xp_verf.oa_base, checksum.value, checksum.length);
|
||||
rqst->rq_xprt->xp_verf.oa_length = (u_int)checksum.length;
|
||||
|
||||
+ gss_release_buffer(&min_stat, &checksum);
|
||||
+
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
@@ -568,6 +578,8 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
||||
gss_qop_t qop;
|
||||
struct svcauth_gss_cache_entry **ce;
|
||||
time_t now;
|
||||
+ enum auth_stat result = AUTH_OK;
|
||||
+ OM_uint32 min_stat;
|
||||
|
||||
gss_log_debug("in svcauth_gss()");
|
||||
|
||||
@@ -621,19 +633,25 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
||||
XDR_DESTROY(&xdrs);
|
||||
|
||||
/* Check version. */
|
||||
- if (gc->gc_v != RPCSEC_GSS_VERSION)
|
||||
- return (AUTH_BADCRED);
|
||||
+ if (gc->gc_v != RPCSEC_GSS_VERSION) {
|
||||
+ result = AUTH_BADCRED;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
/* Check RPCSEC_GSS service. */
|
||||
if (gc->gc_svc != RPCSEC_GSS_SVC_NONE &&
|
||||
gc->gc_svc != RPCSEC_GSS_SVC_INTEGRITY &&
|
||||
- gc->gc_svc != RPCSEC_GSS_SVC_PRIVACY)
|
||||
- return (AUTH_BADCRED);
|
||||
+ gc->gc_svc != RPCSEC_GSS_SVC_PRIVACY) {
|
||||
+ result = AUTH_BADCRED;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
/* Check sequence number. */
|
||||
if (gd->established) {
|
||||
- if (gc->gc_seq > MAXSEQ)
|
||||
- return (RPCSEC_GSS_CTXPROBLEM);
|
||||
+ if (gc->gc_seq > MAXSEQ) {
|
||||
+ result = RPCSEC_GSS_CTXPROBLEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
if ((offset = gd->seqlast - gc->gc_seq) < 0) {
|
||||
gd->seqlast = gc->gc_seq;
|
||||
@@ -643,7 +661,8 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
||||
}
|
||||
else if (offset >= gd->win || (gd->seqmask & (1 << offset))) {
|
||||
*no_dispatch = 1;
|
||||
- return (RPCSEC_GSS_CTXPROBLEM);
|
||||
+ result = RPCSEC_GSS_CTXPROBLEM;
|
||||
+ goto out;
|
||||
}
|
||||
gd->seq = gc->gc_seq;
|
||||
gd->seqmask |= (1 << offset);
|
||||
@@ -654,35 +673,52 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
||||
rqst->rq_svcname = (char *)gd->ctx;
|
||||
}
|
||||
|
||||
+ rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base;
|
||||
+
|
||||
/* Handle RPCSEC_GSS control procedure. */
|
||||
switch (gc->gc_proc) {
|
||||
|
||||
case RPCSEC_GSS_INIT:
|
||||
case RPCSEC_GSS_CONTINUE_INIT:
|
||||
- if (rqst->rq_proc != NULLPROC)
|
||||
- return (AUTH_FAILED); /* XXX ? */
|
||||
+ if (rqst->rq_proc != NULLPROC) {
|
||||
+ result = AUTH_FAILED; /* XXX ? */
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
if (_svcauth_gss_name == GSS_C_NO_NAME) {
|
||||
- if (!svcauth_gss_import_name("nfs"))
|
||||
- return (AUTH_FAILED);
|
||||
+ if (!svcauth_gss_import_name("nfs")) {
|
||||
+ result = AUTH_FAILED;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
- if (!svcauth_gss_acquire_cred(0, GSS_C_NULL_OID_SET))
|
||||
- return (AUTH_FAILED);
|
||||
+ if (!svcauth_gss_acquire_cred()) {
|
||||
+ result = AUTH_FAILED;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (!svcauth_gss_accept_sec_context(rqst, &gr))
|
||||
- return (AUTH_REJECTEDCRED);
|
||||
+ if (!svcauth_gss_accept_sec_context(rqst, &gr)) {
|
||||
+ result = AUTH_REJECTEDCRED;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win)))
|
||||
- return (AUTH_FAILED);
|
||||
+ if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win))) {
|
||||
+ result = AUTH_FAILED;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
*no_dispatch = TRUE;
|
||||
|
||||
call_stat = svc_sendreply(rqst->rq_xprt,
|
||||
(xdrproc_t)xdr_rpc_gss_init_res, (caddr_t)&gr);
|
||||
|
||||
- if (!call_stat)
|
||||
- return (AUTH_FAILED);
|
||||
+ gss_release_buffer(&min_stat, &gr.gr_token);
|
||||
+ free(gr.gr_ctx.value);
|
||||
+
|
||||
+ if (!call_stat) {
|
||||
+ result = AUTH_FAILED;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
if (gr.gr_major == GSS_S_COMPLETE)
|
||||
gd->established = TRUE;
|
||||
@@ -690,27 +726,37 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
||||
break;
|
||||
|
||||
case RPCSEC_GSS_DATA:
|
||||
- if (!svcauth_gss_validate(gd, msg, &qop))
|
||||
- return (RPCSEC_GSS_CREDPROBLEM);
|
||||
+ if (!svcauth_gss_validate(gd, msg, &qop)) {
|
||||
+ result = RPCSEC_GSS_CREDPROBLEM;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq)))
|
||||
- return (AUTH_FAILED);
|
||||
+ if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq))) {
|
||||
+ result = AUTH_FAILED;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
if (!gd->callback_done) {
|
||||
gd->callback_done = TRUE;
|
||||
gd->sec.qop = qop;
|
||||
(void)rpc_gss_num_to_qop(gd->rcred.mechanism,
|
||||
gd->sec.qop, &gd->rcred.qop);
|
||||
- if (!svcauth_gss_callback(rqst, gd))
|
||||
- return (AUTH_REJECTEDCRED);
|
||||
+ if (!svcauth_gss_callback(rqst, gd)) {
|
||||
+ result = AUTH_REJECTEDCRED;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (gd->locked) {
|
||||
if (gd->rcred.service !=
|
||||
- _rpc_gss_svc_to_service(gc->gc_svc))
|
||||
- return (AUTH_FAILED);
|
||||
- if (gd->sec.qop != qop)
|
||||
- return (AUTH_BADVERF);
|
||||
+ _rpc_gss_svc_to_service(gc->gc_svc)) {
|
||||
+ result = AUTH_FAILED;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (gd->sec.qop != qop) {
|
||||
+ result = AUTH_BADVERF;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (gd->sec.qop != qop) {
|
||||
@@ -724,17 +770,25 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
||||
break;
|
||||
|
||||
case RPCSEC_GSS_DESTROY:
|
||||
- if (rqst->rq_proc != NULLPROC)
|
||||
- return (AUTH_FAILED); /* XXX ? */
|
||||
+ if (rqst->rq_proc != NULLPROC) {
|
||||
+ result = AUTH_FAILED; /* XXX ? */
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (!svcauth_gss_validate(gd, msg, &qop))
|
||||
- return (RPCSEC_GSS_CREDPROBLEM);
|
||||
+ if (!svcauth_gss_validate(gd, msg, &qop)) {
|
||||
+ result = RPCSEC_GSS_CREDPROBLEM;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq)))
|
||||
- return (AUTH_FAILED);
|
||||
+ if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq))) {
|
||||
+ result = AUTH_FAILED;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (!svcauth_gss_release_cred())
|
||||
- return (AUTH_FAILED);
|
||||
+ if (!svcauth_gss_release_cred()) {
|
||||
+ result = AUTH_FAILED;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
SVCAUTH_DESTROY(&SVC_XP_AUTH(rqst->rq_xprt));
|
||||
SVC_XP_AUTH(rqst->rq_xprt).svc_ah_ops = svc_auth_none.svc_ah_ops;
|
||||
@@ -743,10 +797,12 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
||||
break;
|
||||
|
||||
default:
|
||||
- return (AUTH_REJECTEDCRED);
|
||||
+ result = AUTH_REJECTEDCRED;
|
||||
break;
|
||||
}
|
||||
- return (AUTH_OK);
|
||||
+out:
|
||||
+ xdr_free((xdrproc_t)xdr_rpc_gss_cred, (caddr_t)gc);
|
||||
+ return result;
|
||||
}
|
||||
|
||||
static bool_t
|
||||
@@ -890,7 +946,6 @@ bool_t
|
||||
rpc_gss_set_svc_name(char *principal, char *mechanism, u_int req_time,
|
||||
u_int UNUSED(program), u_int UNUSED(version))
|
||||
{
|
||||
- gss_OID_set_desc oid_set;
|
||||
rpc_gss_OID oid;
|
||||
char *save;
|
||||
|
||||
@@ -902,14 +957,13 @@ rpc_gss_set_svc_name(char *principal, char *mechanism, u_int req_time,
|
||||
|
||||
if (!rpc_gss_mech_to_oid(mechanism, &oid))
|
||||
goto out_err;
|
||||
- oid_set.count = 1;
|
||||
- oid_set.elements = (gss_OID)oid;
|
||||
|
||||
if (!svcauth_gss_import_name(principal))
|
||||
goto out_err;
|
||||
- if (!svcauth_gss_acquire_cred(req_time, &oid_set))
|
||||
- goto out_err;
|
||||
|
||||
+ _svcauth_req_time = req_time;
|
||||
+ _svcauth_oid_set.count = 1;
|
||||
+ _svcauth_oid_set.elements = (gss_OID)oid;
|
||||
free(_svcauth_svc_name);
|
||||
_svcauth_svc_name = save;
|
||||
return TRUE;
|
@ -1,18 +0,0 @@
|
||||
diff --git a/src/libtirpc.map b/src/libtirpc.map
|
||||
index 063cddd..449b769 100644
|
||||
--- a/src/libtirpc.map
|
||||
+++ b/src/libtirpc.map
|
||||
@@ -316,6 +316,13 @@ TIRPC_0.3.2 {
|
||||
xdr_unixcred;
|
||||
} TIRPC_0.3.1;
|
||||
|
||||
+TIRPC_0.3.3 {
|
||||
+ __getpublickey_LOCAL;
|
||||
+ __key_decryptsession_pk_LOCAL;
|
||||
+ __key_encryptsession_pk_LOCAL;
|
||||
+ __key_gendes_LOCAL;
|
||||
+} TIRPC_0.3.2;
|
||||
+
|
||||
TIRPC_PRIVATE {
|
||||
global:
|
||||
__libc_clntudp_bufcreate;
|
@ -1,41 +0,0 @@
|
||||
xprt->xp_netid can be allocated by makefd_xprt() in
|
||||
svc_fd_create(), so don't blindly overwrite the
|
||||
pointer in svc_tli_create()
|
||||
|
||||
The API expection is the nc_netid passed in will be
|
||||
used for the xp_netid. So the pointer must be
|
||||
freed then re-allocated.
|
||||
|
||||
Reported-by: Michael Theall <mtheall@us.ibm.com>
|
||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||
---
|
||||
src/svc_generic.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/svc_generic.c b/src/svc_generic.c
|
||||
index f49d776..7aae796 100644
|
||||
--- a/src/svc_generic.c
|
||||
+++ b/src/svc_generic.c
|
||||
@@ -283,6 +283,8 @@ svc_tli_create(fd, nconf, bindaddr, sendsz, recvsz)
|
||||
xprt->xp_type = __rpc_socktype2seman(si.si_socktype);
|
||||
|
||||
if (nconf) {
|
||||
+ if (xprt->xp_netid != NULL)
|
||||
+ free(xprt->xp_netid);
|
||||
xprt->xp_netid = strdup(nconf->nc_netid);
|
||||
xprt->xp_tp = strdup(nconf->nc_device);
|
||||
}
|
||||
--
|
||||
2.4.3
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Monitor 25 network devices or servers for free with OpManager!
|
||||
OpManager is web-based network management software that monitors
|
||||
network devices and physical & virtual servers, alerts via email & sms
|
||||
for fault. Monitor 25 devices for free with no restriction. Download now
|
||||
http://ad.doubleclick.net/ddm/clk/292181274;119417398;o
|
||||
_______________________________________________
|
||||
Libtirpc-devel mailing list
|
||||
Libtirpc-devel@lists.sourceforge.net
|
||||
https://lists.sourceforge.net/lists/listinfo/libtirpc-devel
|
@ -1,56 +0,0 @@
|
||||
A rendezvouser socket is defined by a
|
||||
xp_port value of (u_short)-1 which does
|
||||
not work because xp_port is overwritten
|
||||
by svc_com_create() and 65535 is a valid
|
||||
port value.
|
||||
|
||||
To ensure actual connections get freed
|
||||
properly in __svc_vc_dodestroy(), compare
|
||||
the xp_recv value to rendezvous_request.
|
||||
|
||||
Reported-by: Michael Theall <mtheall@us.ibm.com>
|
||||
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||
---
|
||||
src/svc_vc.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/svc_vc.c b/src/svc_vc.c
|
||||
index 9824631..6848c09 100644
|
||||
--- a/src/svc_vc.c
|
||||
+++ b/src/svc_vc.c
|
||||
@@ -392,6 +392,12 @@ svc_vc_destroy(xprt)
|
||||
__svc_vc_dodestroy(xprt);
|
||||
}
|
||||
|
||||
+static bool_t
|
||||
+__svc_rendezvous_socket(xprt)
|
||||
+ SVCXPRT *xprt;
|
||||
+{
|
||||
+ return (xprt->xp_ops->xp_recv == rendezvous_request);
|
||||
+}
|
||||
static void
|
||||
__svc_vc_dodestroy(xprt)
|
||||
SVCXPRT *xprt;
|
||||
@@ -403,7 +409,7 @@ __svc_vc_dodestroy(xprt)
|
||||
|
||||
if (xprt->xp_fd != RPC_ANYFD)
|
||||
(void)close(xprt->xp_fd);
|
||||
- if (xprt->xp_port != 0) {
|
||||
+ if (__svc_rendezvous_socket(xprt)) {
|
||||
/* a rendezvouser socket */
|
||||
r = (struct cf_rendezvous *)xprt->xp_p1;
|
||||
mem_free(r, sizeof (struct cf_rendezvous));
|
||||
--
|
||||
2.4.3
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Monitor 25 network devices or servers for free with OpManager!
|
||||
OpManager is web-based network management software that monitors
|
||||
network devices and physical & virtual servers, alerts via email & sms
|
||||
for fault. Monitor 25 devices for free with no restriction. Download now
|
||||
http://ad.doubleclick.net/ddm/clk/292181274;119417398;o
|
||||
_______________________________________________
|
||||
Libtirpc-devel mailing list
|
||||
Libtirpc-devel@lists.sourceforge.net
|
||||
https://lists.sourceforge.net/lists/listinfo/libtirpc-devel
|
@ -1,88 +0,0 @@
|
||||
diff -Naur a/src/Makefile.am b/src/Makefile.am
|
||||
--- a/src/Makefile.am 2015-06-16 17:35:08.000000000 +0200
|
||||
+++ b/src/Makefile.am 2015-06-17 21:23:05.185276962 +0200
|
||||
@@ -69,7 +69,7 @@
|
||||
endif
|
||||
|
||||
libtirpc_la_SOURCES += key_call.c key_prot_xdr.c getpublickey.c
|
||||
-libtirpc_la_SOURCES += netname.c netnamer.c rtime.c
|
||||
+libtirpc_la_SOURCES += netname.c netnamer.c rpcdname.c rtime.c
|
||||
|
||||
CLEANFILES = cscope.* *~
|
||||
DISTCLEANFILES = Makefile.in
|
||||
diff -Naur a/src/rpcdname.c b/src/rpcdname.c
|
||||
--- a/src/rpcdname.c 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/src/rpcdname.c 2015-06-17 21:23:05.186276982 +0200
|
||||
@@ -0,0 +1,72 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2009, Sun Microsystems, Inc.
|
||||
+ * All rights reserved.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions are met:
|
||||
+ * - Redistributions of source code must retain the above copyright notice,
|
||||
+ * this list of conditions and the following disclaimer.
|
||||
+ * - Redistributions in binary form must reproduce the above copyright notice,
|
||||
+ * this list of conditions and the following disclaimer in the documentation
|
||||
+ * and/or other materials provided with the distribution.
|
||||
+ * - Neither the name of Sun Microsystems, Inc. nor the names of its
|
||||
+ * contributors may be used to endorse or promote products derived
|
||||
+ * from this software without specific prior written permission.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
+ * POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * rpcdname.c
|
||||
+ * Gets the default domain name
|
||||
+ */
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+static char *default_domain = 0;
|
||||
+
|
||||
+static char *
|
||||
+get_default_domain()
|
||||
+{
|
||||
+ char temp[256];
|
||||
+
|
||||
+ if (default_domain)
|
||||
+ return (default_domain);
|
||||
+ if (getdomainname(temp, sizeof(temp)) < 0)
|
||||
+ return (0);
|
||||
+ if ((int) strlen(temp) > 0) {
|
||||
+ default_domain = (char *)malloc((strlen(temp)+(unsigned)1));
|
||||
+ if (default_domain == 0)
|
||||
+ return (0);
|
||||
+ (void) strcpy(default_domain, temp);
|
||||
+ return (default_domain);
|
||||
+ }
|
||||
+ return (0);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This is a wrapper for the system call getdomainname which returns a
|
||||
+ * ypclnt.h error code in the failure case. It also checks to see that
|
||||
+ * the domain name is non-null, knowing that the null string is going to
|
||||
+ * get rejected elsewhere in the NIS client package.
|
||||
+ */
|
||||
+int
|
||||
+__rpc_get_default_domain(domain)
|
||||
+ char **domain;
|
||||
+{
|
||||
+ if ((*domain = get_default_domain()) != 0)
|
||||
+ return (0);
|
||||
+ return (-1);
|
||||
+}
|
@ -1,84 +0,0 @@
|
||||
diff --git a/src/libtirpc.map b/src/libtirpc.map
|
||||
index 449b769..13bc20a 100644
|
||||
--- a/src/libtirpc.map
|
||||
+++ b/src/libtirpc.map
|
||||
@@ -321,6 +321,7 @@ TIRPC_0.3.3 {
|
||||
__key_decryptsession_pk_LOCAL;
|
||||
__key_encryptsession_pk_LOCAL;
|
||||
__key_gendes_LOCAL;
|
||||
+ authdes_pk_create;
|
||||
} TIRPC_0.3.2;
|
||||
|
||||
TIRPC_PRIVATE {
|
||||
diff --git a/src/rpc_soc.c b/src/rpc_soc.c
|
||||
index e146ed4..03bc0d4 100644
|
||||
--- a/src/rpc_soc.c
|
||||
+++ b/src/rpc_soc.c
|
||||
@@ -61,6 +61,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
+#include <rpcsvc/nis.h>
|
||||
|
||||
#include "rpc_com.h"
|
||||
|
||||
@@ -553,6 +554,46 @@ fallback:
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Create the client des authentication object. Obsoleted by
|
||||
+ * authdes_pk_seccreate().
|
||||
+ */
|
||||
+extern AUTH *authdes_pk_seccreate(const char *, netobj *, u_int, const char *,
|
||||
+ const des_block *, nis_server *);
|
||||
+
|
||||
+AUTH *
|
||||
+authdes_pk_create(servername, pkey, window, syncaddr, ckey)
|
||||
+ char *servername; /* network name of server */
|
||||
+ netobj *pkey; /* public key */
|
||||
+ u_int window; /* time to live */
|
||||
+ struct sockaddr *syncaddr; /* optional hostaddr to sync with */
|
||||
+ des_block *ckey; /* optional conversation key to use */
|
||||
+{
|
||||
+ AUTH *nauth;
|
||||
+ char hostname[NI_MAXHOST];
|
||||
+
|
||||
+ if (syncaddr) {
|
||||
+ /*
|
||||
+ * Change addr to hostname, because that is the way
|
||||
+ * new interface takes it.
|
||||
+ */
|
||||
+ switch (syncaddr->sa_family) {
|
||||
+ case AF_INET:
|
||||
+ if (getnameinfo(syncaddr, sizeof(struct sockaddr_in), hostname,
|
||||
+ sizeof hostname, NULL, 0, 0) != 0)
|
||||
+ goto fallback;
|
||||
+ break;
|
||||
+ default:
|
||||
+ goto fallback;
|
||||
+ }
|
||||
+ nauth = authdes_pk_seccreate(servername, pkey, window, hostname, ckey, NULL);
|
||||
+ return (nauth);
|
||||
+ }
|
||||
+fallback:
|
||||
+ return authdes_pk_seccreate(servername, pkey, window, NULL, ckey, NULL);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
* Create a client handle for a unix connection. Obsoleted by clnt_vc_create()
|
||||
*/
|
||||
CLIENT *
|
||||
diff --git a/tirpc/rpc/auth.h b/tirpc/rpc/auth.h
|
||||
index 3e44863..e67779c 100644
|
||||
--- a/tirpc/rpc/auth.h
|
||||
+++ b/tirpc/rpc/auth.h
|
||||
@@ -313,6 +313,8 @@ extern AUTH *authnone_create(void); /* takes no parameters */
|
||||
extern "C" {
|
||||
#endif
|
||||
extern AUTH *authdes_create (char *, u_int, struct sockaddr *, des_block *);
|
||||
+extern AUTH *authdes_pk_create (char *, netobj *, u_int,
|
||||
+ struct sockaddr *, des_block *);
|
||||
extern AUTH *authdes_seccreate (const char *, const u_int, const char *,
|
||||
const des_block *);
|
||||
#ifdef __cplusplus
|
@ -1,59 +0,0 @@
|
||||
diff --git a/src/Makefile.am b/src/Makefile.am
|
||||
index 18b1cec..a29f607 100644
|
||||
--- a/src/Makefile.am
|
||||
+++ b/src/Makefile.am
|
||||
@@ -54,7 +54,7 @@ libtirpc_la_SOURCES = auth_none.c auth_unix.c authunix_prot.c bindresvport.c cln
|
||||
auth_time.c auth_des.c authdes_prot.c debug.c
|
||||
|
||||
## XDR
|
||||
-libtirpc_la_SOURCES += xdr.c xdr_rec.c xdr_array.c xdr_float.c xdr_mem.c xdr_reference.c xdr_stdio.c
|
||||
+libtirpc_la_SOURCES += xdr.c xdr_rec.c xdr_array.c xdr_float.c xdr_mem.c xdr_reference.c xdr_stdio.c xdr_sizeof.c
|
||||
|
||||
if SYMVERS
|
||||
libtirpc_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libtirpc.map
|
||||
diff --git a/src/libtirpc.map b/src/libtirpc.map
|
||||
index 449b769..855d6b3 100644
|
||||
--- a/src/libtirpc.map
|
||||
+++ b/src/libtirpc.map
|
||||
@@ -321,6 +321,7 @@ TIRPC_0.3.3 {
|
||||
__key_encryptsession_pk_LOCAL;
|
||||
__key_gendes_LOCAL;
|
||||
authdes_pk_create;
|
||||
+ xdr_sizeof;
|
||||
} TIRPC_0.3.2;
|
||||
|
||||
TIRPC_PRIVATE {
|
||||
diff --git a/src/xdr_sizeof.c b/src/xdr_sizeof.c
|
||||
index cc5414b..4ecc977 100644
|
||||
--- a/src/xdr_sizeof.c
|
||||
+++ b/src/xdr_sizeof.c
|
||||
@@ -90,7 +90,7 @@ x_inline(xdrs, len)
|
||||
if (xdrs->x_op != XDR_ENCODE) {
|
||||
return (NULL);
|
||||
}
|
||||
- if (len < (u_int)xdrs->x_base) {
|
||||
+ if (len < (u_int) (long int) xdrs->x_base) {
|
||||
/* x_private was already allocated */
|
||||
xdrs->x_handy += len;
|
||||
return ((int32_t *) xdrs->x_private);
|
||||
@@ -102,7 +102,7 @@ x_inline(xdrs, len)
|
||||
xdrs->x_base = 0;
|
||||
return (NULL);
|
||||
}
|
||||
- xdrs->x_base = (caddr_t) len;
|
||||
+ xdrs->x_base = (void *) (long) len;
|
||||
xdrs->x_handy += len;
|
||||
return ((int32_t *) xdrs->x_private);
|
||||
}
|
||||
diff --git a/tirpc/rpc/xdr.h b/tirpc/rpc/xdr.h
|
||||
index 64069ab..904e5bb 100644
|
||||
--- a/tirpc/rpc/xdr.h
|
||||
+++ b/tirpc/rpc/xdr.h
|
||||
@@ -327,6 +327,7 @@ extern bool_t xdr_hyper(XDR *, quad_t *);
|
||||
extern bool_t xdr_u_hyper(XDR *, u_quad_t *);
|
||||
extern bool_t xdr_longlong_t(XDR *, quad_t *);
|
||||
extern bool_t xdr_u_longlong_t(XDR *, u_quad_t *);
|
||||
+extern u_long xdr_sizeof(xdrproc_t, void *);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,39 +0,0 @@
|
||||
diff --git a/src/rpc_soc.c b/src/rpc_soc.c
|
||||
index e146ed4..9d555d3 100644
|
||||
--- a/src/rpc_soc.c
|
||||
+++ b/src/rpc_soc.c
|
||||
@@ -531,7 +531,6 @@ authdes_create(servername, window, syncaddr, ckey)
|
||||
struct sockaddr *syncaddr; /* optional hostaddr to sync with */
|
||||
des_block *ckey; /* optional conversation key to use */
|
||||
{
|
||||
- AUTH *dummy;
|
||||
AUTH *nauth;
|
||||
char hostname[NI_MAXHOST];
|
||||
|
||||
@@ -540,16 +539,20 @@ authdes_create(servername, window, syncaddr, ckey)
|
||||
* Change addr to hostname, because that is the way
|
||||
* new interface takes it.
|
||||
*/
|
||||
- if (getnameinfo(syncaddr, sizeof(syncaddr), hostname,
|
||||
- sizeof hostname, NULL, 0, 0) != 0)
|
||||
- goto fallback;
|
||||
-
|
||||
+ switch (syncaddr->sa_family) {
|
||||
+ case AF_INET:
|
||||
+ if (getnameinfo(syncaddr, sizeof(struct sockaddr_in), hostname,
|
||||
+ sizeof hostname, NULL, 0, 0) != 0)
|
||||
+ goto fallback;
|
||||
+ break;
|
||||
+ default:
|
||||
+ goto fallback;
|
||||
+ }
|
||||
nauth = authdes_seccreate(servername, window, hostname, ckey);
|
||||
return (nauth);
|
||||
}
|
||||
fallback:
|
||||
- dummy = authdes_seccreate(servername, window, NULL, ckey);
|
||||
- return (dummy);
|
||||
+ return authdes_seccreate(servername, window, NULL, ckey);
|
||||
}
|
||||
|
||||
/*
|
@ -1,12 +0,0 @@
|
||||
diff --git a/tirpc/rpc/svc.h b/tirpc/rpc/svc.h
|
||||
index 8273c95..f647095 100644
|
||||
--- a/tirpc/rpc/svc.h
|
||||
+++ b/tirpc/rpc/svc.h
|
||||
@@ -88,6 +88,7 @@ enum xprt_stat {
|
||||
*/
|
||||
typedef struct __rpc_svcxprt {
|
||||
int xp_fd;
|
||||
+#define xp_sock xp_fd
|
||||
u_short xp_port; /* associated port number */
|
||||
const struct xp_ops {
|
||||
/* receive incoming requests */
|
@ -1 +1 @@
|
||||
libtirpc1
|
||||
libtirpc3
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2008a379f37f2c5d5a87a568b06707422cc3e4f5da305f7fb71f3f4c6d473ffc
|
||||
size 491373
|
3
libtirpc-1.0.1.tar.bz2
Normal file
3
libtirpc-1.0.1.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5156974f31be7ccbc8ab1de37c4739af6d9d42c87b1d5caf4835dda75fcbb89e
|
||||
size 495125
|
@ -1,3 +1,35 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Nov 17 12:55:40 CET 2015 - kukuk@suse.de
|
||||
|
||||
- Update to libtirpc-1.0.1
|
||||
- new major soname
|
||||
- Adjust auth code to match other RPC implementations
|
||||
- Implement more gss auth stuff
|
||||
- use poll() instead of select() in svc_run()
|
||||
- Add more sunrpc compat functions
|
||||
- Sync compat headers with real functions
|
||||
|
||||
- Drop 005-missing-symvers.patch (upstream)
|
||||
- Drop 006-memleak1.patch (upstream)
|
||||
- Drop 007-memleak2.patch (upstream)
|
||||
- Drop 008-fix-undef-ref.patch (upstream)
|
||||
- Drop 009-authdes_pk_create.patch (upstream)
|
||||
- Drop 010-xdr_sizeof.patch (upstream)
|
||||
- Drop 011-authdes_create.patch (upstream)
|
||||
- Drop 012-xp_sock.patch (upstream)
|
||||
- Drop 099-poll.patch (upstream)
|
||||
- Add 005-libtirpc-1.0.2-rc1.patch (fixes deadlock)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jul 16 15:46:00 CEST 2015 - kukuk@suse.de
|
||||
|
||||
- Update 099-poll.patch with newest version send upstream.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jul 10 14:56:02 CEST 2015 - kukuk@suse.de
|
||||
|
||||
- Add 099-poll.patch: change svc_run from select() to poll().
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jul 9 10:47:08 CEST 2015 - kukuk@suse.de
|
||||
|
||||
|
@ -17,9 +17,8 @@
|
||||
|
||||
|
||||
Name: libtirpc
|
||||
# src/crypt_client.c tirpc/spinlock.h and tirpc/rpcsvc/crypt.x have the BSD
|
||||
# advertising clause
|
||||
Version: 0.3.2
|
||||
# src/crypt_client.c and tirpc/rpcsvc/crypt.x have the BSD advertising clause
|
||||
Version: 1.0.1
|
||||
Release: 0
|
||||
Summary: Transport Independent RPC Library
|
||||
License: BSD-4-Clause
|
||||
@ -33,26 +32,18 @@ BuildRequires: autoconf
|
||||
BuildRequires: libtool
|
||||
BuildRequires: pkg-config
|
||||
Url: http://sourceforge.net/projects/libtirpc/
|
||||
# http://downloads.sourceforge.net/project/%{name}/%{name}/%{version}/%{name}-%{version}.tar.bz2
|
||||
Source: %{name}-%{version}.tar.bz2
|
||||
Source1: baselibs.conf
|
||||
Patch0: 000-bindresvport_blacklist.patch
|
||||
# Patch2 is only needed for SLES11
|
||||
Patch2: 002-old-automake.patch
|
||||
Patch4: 004-netconfig-prefer-IPv6.patch
|
||||
Patch5: 005-missing-symvers.patch
|
||||
Patch6: 006-memleak1.patch
|
||||
Patch7: 007-memleak2.patch
|
||||
Patch8: 008-fix-undef-ref.patch
|
||||
Patch9: 009-authdes_pk_create.patch
|
||||
Patch10: 010-xdr_sizeof.patch
|
||||
Patch11: 011-authdes_create.patch
|
||||
Patch12: 012-xp_sock.patch
|
||||
Patch5: 005-libtirpc-1.0.2-rc1.patch
|
||||
Patch25: patch6_7.diff
|
||||
# Patch37 is only needed on openSUSE >= 13.1, SLE >= 12
|
||||
Patch37: libtirpc-new-path-rpcbindsock.patch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
%define debug_package_requires libtirpc1 = %{version}-%{release}
|
||||
%define debug_package_requires libtirpc3 = %{version}-%{release}
|
||||
|
||||
%description
|
||||
The Transport Independent RPC library (TI-RPC) is a replacement for the
|
||||
@ -60,11 +51,11 @@ standard SunRPC library in glibc which does not support IPv6 addresses.
|
||||
This implementation allows the support of other transports than UDP and
|
||||
TCP over IPv4
|
||||
|
||||
%package -n libtirpc1
|
||||
%package -n libtirpc3
|
||||
Summary: Transport Independent RPC Library
|
||||
Group: System/Libraries
|
||||
|
||||
%description -n libtirpc1
|
||||
%description -n libtirpc3
|
||||
The Transport Independent RPC library (TI-RPC) is a replacement for the
|
||||
standard SunRPC library in glibc which does not support IPv6 addresses.
|
||||
This implementation allows the support of other transports than UDP and
|
||||
@ -76,7 +67,7 @@ TCP over IPv4
|
||||
Summary: Transport Independent RPC Library
|
||||
Group: Development/Libraries/C and C++
|
||||
Requires: glibc-devel
|
||||
Requires: libtirpc1 = %{version}
|
||||
Requires: libtirpc3 = %{version}
|
||||
|
||||
%description devel
|
||||
The Transport Independent RPC library (TI-RPC) is a replacement for the
|
||||
@ -90,13 +81,6 @@ TCP over IPv4
|
||||
%patch2 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch25 -p1
|
||||
%if 0%{suse_version} >= 1310
|
||||
%patch37 -p1
|
||||
@ -118,7 +102,7 @@ export STRIP_KEEP_SYMTAB=libtirpc*.so*
|
||||
# NO_BRP_CHECK_ROOTFS is for SLES11 only, but does not harm for Factory
|
||||
export NO_BRP_CHECK_ROOTFS=true
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
# move devel so link to %{_libdir}
|
||||
# move devel so link to _libdir
|
||||
mkdir -p $RPM_BUILD_ROOT%{_libdir}
|
||||
%{__ln_s} -v /%{_lib}/$(readlink %{buildroot}/%{_lib}/%{name}.so) %{buildroot}%{_libdir}/%{name}.so
|
||||
%{__rm} -v %{buildroot}/%{_lib}/%{name}.{la,so}
|
||||
@ -127,14 +111,14 @@ mv -v $RPM_BUILD_ROOT/%{_lib}/pkgconfig $RPM_BUILD_ROOT/%{_libdir}
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post -n libtirpc1 -p /sbin/ldconfig
|
||||
%post -n libtirpc3 -p /sbin/ldconfig
|
||||
|
||||
%postun -n libtirpc1 -p /sbin/ldconfig
|
||||
%postun -n libtirpc3 -p /sbin/ldconfig
|
||||
|
||||
%files -n libtirpc1
|
||||
%files -n libtirpc3
|
||||
%defattr(-,root,root)
|
||||
%config %{_sysconfdir}/netconfig
|
||||
/%{_lib}/libtirpc.so.1*
|
||||
/%{_lib}/libtirpc.so.3*
|
||||
%{_mandir}/man5/netconfig.5.gz
|
||||
|
||||
%files devel
|
||||
|
Loading…
Reference in New Issue
Block a user