diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 7627ade2fa2737b478e3e03e983b8c398cc707a9..42f0efcdaa1883eeed0a173e95a5994f9e1a73f2 100755
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -3191,7 +3191,8 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies
 	/* Start pessimistic */
 	int res = -1;
 	int version = 2;
-	struct iax2_user *user;
+	struct iax2_user *user, *best = NULL;
+	int bestscore = 0;
 	int gotcapability=0;
 	if (!iaxs[callno])
 		return res;
@@ -3240,11 +3241,45 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies
 			&& ast_apply_ha(user->ha, sin) 	/* Access is permitted from this IP */
 			&& (!strlen(iaxs[callno]->context) ||			/* No context specified */
 			     apply_context(user->contexts, iaxs[callno]->context))) {			/* Context is permitted */
-			break;
+			if (strlen(iaxs[callno]->username)) {
+				/* Exact match, stop right now. */
+				best = user;
+				break;
+			} else if (!strlen(user->secret)) {
+				/* No required authentication */
+				if (user->ha) {
+					/* There was host authentication and we passed, bonus! */
+					if (bestscore < 4) {
+						bestscore = 4;
+						best = user;
+					}
+				} else {
+					/* No host access, but no secret, either, not bad */
+					if (bestscore < 3) {
+						bestscore = 3;
+						best = user;
+					}
+				}
+			} else {
+				if (user->ha) {
+					/* Authentication, but host access too, eh, it's something.. */
+					if (bestscore < 2) {
+						bestscore = 2;
+						best = user;
+					}
+				} else {
+					/* Authentication and no host access...  This is our baseline */
+					if (bestscore < 1) {
+						bestscore = 1;
+						best = user;
+					}
+				}
+			}
 		}
 		user = user->next;	
 	}
 	ast_mutex_unlock(&userl.lock);
+	user = best;
 #ifdef MYSQL_FRIENDS
 	if (!user && mysql && strlen(iaxs[callno]->username) && (strlen(iaxs[callno]->username) < 128)) {
 		user = mysql_user(iaxs[callno]->username);