Synopsis: YP+YPLDAP+AC interaction issue
Category: unknown
Environment:
System : OpenBSD 6.3
Details : OpenBSD 6.3
Architecture: OpenBSD.amd64
Machine : amd64
Description:
The system is configured to us YP and ypldap(8) for access to
remote
accounts. The system also has accounting ac(8) enabled. Under
normal
condition the system runs without issue. When the system is
rebooted
and the ethernet cable is not plugged in, the system will fail
to
complete the rc(8) init script. Using ^C repeatedly will get
the
user to a login prompt, however when the user tries to login
with
any account, including root, it will fail to complete the login
process.
The error that is received is a "yp_first: RPC: connection
timeout".
The error message is repeated indefinitely.
How-To-Repeat:
Install a base system. Configure to use ypldap(8) against any
LDAP
server. Configure accounting to start at boot. The environment
I
tested against was Microsoft Active Directory. Configure
accounting
on boot. Unplug all ethernet cables and reboot the system.
Fix:
Attached is a patch I created to limit the the number of times a
timeout
can occur. This patch updates libc and is probably not the
correct way
to handle this issue, but is does work for my use case.
--- lib/libc/yp/ypinternal.h.orig Wed Sep 19 08:04:59 2018
+++ lib/libc/yp/ypinternal.h Wed Sep 19 08:05:26 2018
@@ -43,6 +43,7 @@
#define BINDINGDIR "/var/yp/binding"
#define YPBINDLOCK "/var/run/ypbind.lock"
+#define YPMAXTRIES 2
__BEGIN_HIDDEN_DECLS
extern struct dom_binding *_ypbindlist;
--- lib/libc/yp/yp_first.c.orig Sun Sep 13 15:57:28 2015
+++ lib/libc/yp/yp_first.c Wed Sep 19 08:07:12 2018
@@ -70,7 +70,12 @@
if (tries++)
clnt_perror(ysd->dom_client, "yp_first: clnt_call");
ysd->dom_vers = -1;
- goto again;
+ if (tries < YPMAXTRIES)
+ goto again;
+ else {
+ r = YPERR_YPSERV;
+ goto end;
+ }
}
if (!(r = ypprot_err(yprkv.stat))) {
*outkeylen = yprkv.key.keydat_len;
@@ -87,6 +92,7 @@
}
}
xdr_free(xdr_ypresp_key_val, (char *) &yprkv);
+end:
_yp_unbind(ysd);
return r;
}
--- lib/libc/yp/yp_maplist.c.orig Wed Sep 19 06:46:54 2018
+++ lib/libc/yp/yp_maplist.c Wed Sep 19 08:06:31 2018
@@ -57,10 +57,16 @@
if (tries++)
clnt_perror(ysd->dom_client, "yp_maplist: clnt_call");
ysd->dom_vers = -1;
- goto again;
+ if (tries < YPMAXTRIES) {
+ goto again;
+ } else {
+ r = YPERR_YPSERV;
+ goto end;
+ }
}
*outmaplist = ypml.maps;
/* NO: xdr_free(xdr_ypresp_maplist, &ypml); */
+end:
_yp_unbind(ysd);
return ypprot_err(ypml.stat);
}
--- lib/libc/yp/yp_master.c.orig Wed Sep 19 06:51:48 2018
+++ lib/libc/yp/yp_master.c Wed Sep 19 08:06:39 2018
@@ -66,13 +66,19 @@
if (tries++)
clnt_perror(ysd->dom_client, "yp_master: clnt_call");
ysd->dom_vers = -1;
- goto again;
+ if (tries < YPMAXTRIES) {
+ goto again;
+ } else {
+ r = YPERR_YPSERV;
+ goto end;
+ }
}
if (!(r = ypprot_err(yprm.stat))) {
if ((*outname = strdup(yprm.peer)) == NULL)
r = YPERR_RESRC;
}
xdr_free(xdr_ypresp_master, (char *) &yprm);
+end:
_yp_unbind(ysd);
return r;
}
--- lib/libc/yp/ypmatch_cache.c.orig Wed Sep 19 06:55:03 2018
+++ lib/libc/yp/ypmatch_cache.c Wed Sep 19 08:06:53 2018
@@ -188,7 +188,12 @@
if (tries++)
clnt_perror(ysd->dom_client, "yp_match: clnt_call");
ysd->dom_vers = -1;
- goto again;
+ if (tries < YPMAXTRIES) {
+ goto again;
+ } else {
+ r = YPERR_YPSERV;
+ goto out2;
+ }
}
if (!(r = ypprot_err(yprv.stat))) {
*outvallen = yprv.val.valdat_len;
@@ -206,6 +211,7 @@
}
out:
xdr_free(xdr_ypresp_val, (char *) &yprv);
+out2:
_yp_unbind(ysd);
return r;
}
@@ -249,7 +255,12 @@
if (tries++)
clnt_perror(ysd->dom_client, "yp_next: clnt_call");
ysd->dom_vers = -1;
- goto again;
+ if (tries < YPMAXTRIES) {
+ goto again;
+ } else {
+ r = YPERR_YPSERV;
+ goto out3;
+ }
}
if (!(r = ypprot_err(yprkv.stat))) {
*outkeylen = yprkv.key.keydat_len;
@@ -266,6 +277,7 @@
}
}
xdr_free(xdr_ypresp_key_val, (char *) &yprkv);
+out3:
_yp_unbind(ysd);
return r;
}