Blob Blame History Raw
autofs-5.1.6 - improve sss setautomntent() error handling

From: Ian Kent <raven@themaw.net>

Recent versions of the sss autofs access library will return EHOSTDOWN
if the backend server is down.

The presence of this improvement in error handling is determined by an
added function to get the sss autofs protocol version.

Update the setautomntent() function to use this.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG            |    1 +
 modules/lookup_sss.c |   72 ++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 141658d..5ccd787 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -99,6 +99,7 @@ xx/xx/2018 autofs-5.1.5
 - add support for new sss autofs proto version call.
 - fix retries check in setautomntent_wait().
 - refactor sss setautomntent().
+- improve sss setautomntent() error handling.
 
 19/12/2017 autofs-5.1.4
 - fix spec file url.
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
index 011b232..e1ed83c 100644
--- a/modules/lookup_sss.c
+++ b/modules/lookup_sss.c
@@ -259,16 +259,37 @@ static int setautomntent_wait(unsigned int logopt,
 	*sss_ctxt = NULL;
 
 	retries = defaults_get_sss_master_map_wait();
-	if (retries <= 0)
-		return ENOENT;
+
+	/* If sss_master_map_wait is not set in the autofs
+	 * configuration give it a sensible value since we
+	 * want to wait for a host that's down in case it
+	 * comes back up.
+	 */
+	if (retries <= 0) {
+		/* Protocol version 0 cant't tell us about
+		 * a host being down, return not found.
+		 */
+		if (proto_version(ctxt) == 0)
+			return ENOENT;
+		retries = 10;
+	}
+
+	warn(logopt,
+	     "can't connect to sssd, retry for %d seconds",
+	     retries);
 
 	while (++retry <= retries) {
 		struct timespec t = { SSS_WAIT_INTERVAL, 0 };
 		struct timespec r;
 
 		ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt);
-		if (ret != ENOENT)
-			break;
+		if (proto_version(ctxt) == 0) {
+			if (ret != ENOENT)
+				break;
+		} else {
+			if (ret != EHOSTDOWN)
+				break;
+		}
 
 		if (*sss_ctxt) {
 			free(*sss_ctxt);
@@ -279,17 +300,17 @@ static int setautomntent_wait(unsigned int logopt,
 			memcpy(&t, &r, sizeof(struct timespec));
 	}
 
-
-	if (ret) {
+	if (!ret)
+		info(logopt, "successfully connected to sssd");
+	else {
 		if (*sss_ctxt) {
 			free(*sss_ctxt);
 			*sss_ctxt = NULL;
 		}
 
-		if (retry > retries)
+		if (proto_version(ctxt) == 0 && retry > retries)
 			ret = ETIMEDOUT;
 	}
-
 	return ret;
 }
 
@@ -298,35 +319,50 @@ static int setautomntent(unsigned int logopt,
 {
 	char buf[MAX_ERR_BUF];
 	char *estr;
+	int err = NSS_STATUS_UNAVAIL;
 	int ret;
 
 	ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt);
 	if (ret) {
-		if (ret == ECONNREFUSED)
-			return NSS_STATUS_UNKNOWN;
-
-		if (ret != ENOENT)
+		if (ret == ECONNREFUSED) {
+			err = NSS_STATUS_UNKNOWN;
 			goto error;
+		}
+
+		if (proto_version(ctxt) == 0) {
+			if (ret != ENOENT)
+				goto error;
+		} else {
+			if (ret != ENOENT && ret != EHOSTDOWN)
+				goto error;
+		}
 
 		ret = setautomntent_wait(logopt, ctxt, sss_ctxt);
 		if (ret) {
-			if (ret == ECONNREFUSED)
-				return NSS_STATUS_UNKNOWN;
-			if (ret == ENOENT)
-				return NSS_STATUS_NOTFOUND;
+			if (ret == ECONNREFUSED) {
+				err = NSS_STATUS_UNKNOWN;
+				goto error;
+			}
+			if (ret == ETIMEDOUT)
+				goto error;
+			if (ret == ENOENT) {
+				err = NSS_STATUS_NOTFOUND;
+				goto free;
+			}
 			goto error;
 		}
 	}
-	return ret;
+	return NSS_STATUS_SUCCESS;
 
 error:
 	estr = strerror_r(ret, buf, MAX_ERR_BUF);
 	error(logopt, MODPREFIX "setautomntent: %s", estr);
+free:
 	if (*sss_ctxt) {
 		free(*sss_ctxt);
 		*sss_ctxt = NULL;
 	}
-	return NSS_STATUS_UNAVAIL;
+	return err;
 }
 
 static int endautomntent(unsigned int logopt,