Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 130701790bf2d95e902edf16031ff596 > files > 250

autofs-5.0.1-0.rc2.164.el5_8.src.rpm

diff -up autofs-5.0.1/modules/lookup_ldap.c.ldap-percent-hack autofs-5.0.1/modules/lookup_ldap.c
--- autofs-5.0.1/modules/lookup_ldap.c.ldap-percent-hack	2007-10-18 17:25:11.000000000 +0800
+++ autofs-5.0.1/modules/lookup_ldap.c	2007-10-18 17:25:40.000000000 +0800
@@ -1269,50 +1269,68 @@ static int read_one_map(struct autofs_po
 		}
 
 		/*
-		 * By definition keys must be unique within
-		 * each map entry
+		 * By definition keys should be unique within each map entry,
+		 * but as always there are exceptions.
 		 */
 		k_val = NULL;
 		k_len = 0;
 
 		/*
-		 * Keys must be unique so, in general, there shouldn't be
+		 * Keys should be unique so, in general, there shouldn't be
 		 * more than one attribute value. We make an exception for
 		 * wildcard entries as people may have values for '*' or
 		 * '/' for compaibility reasons. We use the '/' as the
 		 * wildcard in LDAP but allow '*' as well to allow for
 		 * people using older schemas that allow '*' as a key
-		 * value.
+		 * value. Another case where there can be multiple key
+		 * values is when people have used the "%" hack to specify
+		 * case matching ctriteria in a caase insensitive attribute.
 		 */
 		count = ldap_count_values_len(bvKey);
-		if (count > 2) {
-			error(ap->logopt,
-			      MODPREFIX
-			      "key %.*s has duplicate entries - ignoring",
-			      bvKey[0]->bv_len, bvKey[0]->bv_val);
-			goto next;
-		} else if (count == 2) {
+		if (count > 1) {
 			unsigned int i;
 
 			/* Check for the "/" and "*" and use as "/" if found */
 			for (i = 0; i < count; i++) {
-				/* check for wildcard */
-				if (bvKey[i]->bv_len != 1)
-					continue;
-				if (*bvKey[i]->bv_val != '/' &&
-				    *bvKey[i]->bv_val != '*')
+				bvKey[i]->bv_val[bvKey[i]->bv_len] = '\0';
+
+				/*
+				 * If multiple entries are present they could
+				 * be the result of people using the "%" hack so
+				 * ignore them.
+				 */
+				if (strchr(bvKey[i]->bv_val, '%'))
 					continue;
-				/* always use '/' internally */
-				*bvKey[i]->bv_val = '/';
+
+				/* check for wildcard */
+				if (bvKey[i]->bv_len == 1 &&
+				    (*bvKey[i]->bv_val == '/' ||
+				     *bvKey[i]->bv_val == '*')) {
+					/* always use '/' internally */
+					*bvKey[i]->bv_val = '/';
+					k_val = bvKey[i]->bv_val;
+					k_len = 1;
+					break;
+				}
+
+				/*
+				 * We have a result from LDAP so this is a
+				 * valid entry. Set the result to the LDAP
+				 * key that isn't a wildcard and doesn't have
+				 * any "%" hack values present. This should be
+				 * the case insensitive match string for the
+				 * nis schema, the default value.
+				 */
 				k_val = bvKey[i]->bv_val;
-				k_len = 1;
+				k_len = bvKey[i]->bv_len;
+
 				break;
 			}
 
 			if (!k_val) {
 				error(ap->logopt,
 				      MODPREFIX
-				      "key %.*s has duplicate entries - ignoring",
+				      "invalid entry %.*s - ignoring",
 				      bvKey[0]->bv_len, bvKey[0]->bv_val);
 				goto next;
 			}
@@ -1554,7 +1572,10 @@ static int lookup_one(struct autofs_poin
 			continue;
 		}
 
-		/* By definition keys must be unique within each map entry */
+		/*
+		 * By definition keys should be unique within each map entry,
+		 * but as always there are exceptions.
+		 */
 		k_val = NULL;
 		k_len = 0;
 
@@ -1565,37 +1586,53 @@ static int lookup_one(struct autofs_poin
 		 * '/' for compaibility reasons. We use the '/' as the
 		 * wildcard in LDAP but allow '*' as well to allow for
 		 * people using older schemas that allow '*' as a key
-		 * value.
+		 * value. Another case where there can be multiple key
+		 * values is when people have used the "%" hack to specify
+		 * case matching ctriteria in a caase insensitive attribute.
 		 */
 		count = ldap_count_values_len(bvKey);
-		if (count > 2) {
-			error(ap->logopt,
-			      MODPREFIX
-			      "key %.*s has duplicate entries - ignoring",
-			      bvKey[0]->bv_len, bvKey[0]->bv_val);
-			goto next;
-		} else if (count == 2) {
+		if (count > 1) {
 			unsigned int i;
 
 			/* Check for the "/" and "*" and use as "/" if found */
 			for (i = 0; i < count; i++) {
-				/* check for wildcard */
-				if (bvKey[i]->bv_len != 1)
-					continue;
-				if (*bvKey[i]->bv_val != '/' &&
-				    *bvKey[i]->bv_val != '*')
+				bvKey[i]->bv_val[bvKey[i]->bv_len] = '\0';
+
+				/*
+				 * If multiple entries are present they could
+				 * be the result of people using the "%" hack so
+				 * ignore them.
+				 */
+				if (strchr(bvKey[i]->bv_val, '%'))
 					continue;
-				/* always use '/' internally */
-				*bvKey[i]->bv_val = '/';
-				k_val = bvKey[i]->bv_val;
-				k_len = 1;
+
+				/* check for wildcard */
+				if (bvKey[i]->bv_len == 1 &&
+				    (*bvKey[i]->bv_val == '/' ||
+				     *bvKey[i]->bv_val == '*')) {
+					/* always use '/' internally */
+					*bvKey[i]->bv_val = '/';
+					k_val = bvKey[i]->bv_val;
+					k_len = 1;
+					break;
+				}
+
+				/*
+				 * The key was matched by LDAP so this is a
+				 * valid entry. Set the result key to the
+				 * lookup key to provide the mixed case
+				 * matching provided by the "%" hack.
+				 */
+				k_val = qKey;
+				k_len = strlen(qKey);
+
 				break;
 			}
 
 			if (!k_val) {
 				error(ap->logopt,
-					MODPREFIX "key %.*s has duplicate entries",
-					bvKey[0]->bv_len, bvKey[0]->bv_val);
+					MODPREFIX "no valid key found for %.*s",
+					qKey_len, qKey);
 				ret = CHE_FAIL;
 				goto next;
 			}