db_get_auth_data / db_get_auc: clarify return values

Differentiate between "IMSI unknown" and "IMSI has no auth data": in case of
known IMSI lacking auth data, return -ENOKEY instead of -ENOENT.

Fix API doc comments to reflect what the functions actually return, on top of
adding the -ENOKEY detail.

Adjust db_test expectations from -ENOENT to -ENOKEY where appropriate.

Adjust VTY and CTRL command rc evaluation.

A subsequent patch will use these return values to log details on each of these
situations.

Change-Id: Icf6304d23585f2ed45e050fa27c787f2d66fd3f7
diff --git a/src/ctrl.c b/src/ctrl.c
index 3e81661..8ae9d7c 100644
--- a/src/ctrl.c
+++ b/src/ctrl.c
@@ -228,11 +228,16 @@
 
 	rc = db_get_auth_data(hlr->dbc, imsi, &aud2g, &aud3g, NULL);
 
-	if (rc == -ENOENT) {
+	switch (rc) {
+	case 0:
+		break;
+	case -ENOENT:
+	case -ENOKEY:
 		/* No auth data found, tell the print*() functions about it. */
 		aud2g.algo = OSMO_AUTH_ALG_NONE;
 		aud3g.algo = OSMO_AUTH_ALG_NONE;
-	} else if (rc) {
+		break;
+	default:
 		cmd->reply = "Error retrieving authentication data.";
 		return CTRL_CMD_ERROR;
 	}
@@ -258,11 +263,16 @@
 
 	rc = db_get_auth_data(hlr->dbc, subscr.imsi, &aud2g, &aud3g, NULL);
 
-	if (rc == -ENOENT) {
+	switch (rc) {
+	case 0:
+		break;
+	case -ENOENT:
+	case -ENOKEY:
 		/* No auth data found, tell the print*() functions about it. */
 		aud2g.algo = OSMO_AUTH_ALG_NONE;
 		aud3g.algo = OSMO_AUTH_ALG_NONE;
-	} else if (rc) {
+		break;
+	default:
 		cmd->reply = "Error retrieving authentication data.";
 		return CTRL_CMD_ERROR;
 	}
diff --git a/src/db_auc.c b/src/db_auc.c
index 7bbc93f..5fb5e3a 100644
--- a/src/db_auc.c
+++ b/src/db_auc.c
@@ -74,7 +74,9 @@
 }
 
 /* obtain the authentication data for a given imsi
- * returns -1 in case of error, 0 for unknown IMSI, 1 for success */
+ * returns 0 for success, negative value on error:
+ * -ENOENT if the IMSI is not known, -ENOKEY if the IMSI is known but has no auth data,
+ * -EIO on db failure */
 int db_get_auth_data(struct db_context *dbc, const char *imsi,
 		     struct osmo_sub_auth_data *aud2g,
 		     struct osmo_sub_auth_data *aud3g,
@@ -163,15 +165,16 @@
 		LOGAUC(imsi, LOGL_DEBUG, "No 3G Auth Data\n");
 
 	if (aud2g->type == 0 && aud3g->type == 0)
-		ret = -ENOENT;
+		ret = -ENOKEY;
 
 out:
 	db_remove_reset(stmt);
 	return ret;
 }
 
-/* return -1 in case of error, 0 for unknown imsi, positive for number
- * of vectors generated */
+/* return number of vectors generated, negative value on error:
+ * -ENOENT if the IMSI is not known, -ENOKEY if the IMSI is known but has no auth data,
+ * -EIO on db failure */
 int db_get_auc(struct db_context *dbc, const char *imsi,
 	       unsigned int auc_3g_ind, struct osmo_auth_vector *vec,
 	       unsigned int num_vec, const uint8_t *rand_auts,
diff --git a/src/hlr.c b/src/hlr.c
index bcae3b5..58f94f3 100644
--- a/src/hlr.c
+++ b/src/hlr.c
@@ -71,6 +71,9 @@
 		gsup_out.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR;
 		switch (rc) {
 		case 0:
+			/* 0 means "0 tuples generated", which shouldn't happen.
+			 * Treat the same as "no auth data". */
+		case -ENOKEY:
 		case -ENOENT:
 			gsup_out.cause = GMM_CAUSE_IMSI_UNKNOWN;
 			break;
diff --git a/src/hlr_vty_subscr.c b/src/hlr_vty_subscr.c
index 0a9ba76..5a300a7 100644
--- a/src/hlr_vty_subscr.c
+++ b/src/hlr_vty_subscr.c
@@ -72,14 +72,17 @@
 	OSMO_ASSERT(g_hlr);
 	rc = db_get_auth_data(g_hlr->dbc, subscr->imsi, &aud2g, &aud3g, NULL);
 
-	if (rc) {
-		if (rc == -ENOENT) {
-			aud2g.algo = OSMO_AUTH_ALG_NONE;
-			aud3g.algo = OSMO_AUTH_ALG_NONE;
-		} else {
-			vty_out(vty, "%% Error retrieving data from database (%d)%s", rc, VTY_NEWLINE);
-			return;
-		}
+	switch (rc) {
+	case 0:
+		break;
+	case -ENOENT:
+	case -ENOKEY:
+		aud2g.algo = OSMO_AUTH_ALG_NONE;
+		aud3g.algo = OSMO_AUTH_ALG_NONE;
+		break;
+	default:
+		vty_out(vty, "%% Error retrieving data from database (%d)%s", rc, VTY_NEWLINE);
+		return;
 	}
 
 	if (aud2g.type != OSMO_AUTH_TYPE_NONE && aud2g.type != OSMO_AUTH_TYPE_GSM) {