]>
Commit | Line | Data |
---|---|---|
3d551623 PG |
1 | diff --git a/CHANGELOG b/CHANGELOG |
2 | index fcfbe62..c29d577 100644 | |
3 | --- a/CHANGELOG | |
4 | +++ b/CHANGELOG | |
5 | @@ -51,6 +51,7 @@ | |
6 | - improve handling of server not available. | |
7 | - fix LDAP_URI server selection. | |
8 | - add authentication option for using an external credential cache. | |
9 | +- expand support for the "%" hack. | |
10 | ||
11 | 18/06/2007 autofs-5.0.2 | |
12 | ----------------------- | |
13 | diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c | |
14 | index 13fbff7..65f1fda 100644 | |
15 | --- a/modules/lookup_ldap.c | |
16 | +++ b/modules/lookup_ldap.c | |
17 | @@ -1411,6 +1411,140 @@ next: | |
18 | return NSS_STATUS_SUCCESS; | |
19 | } | |
20 | ||
21 | +/* | |
22 | + * Deal with encode and decode of % hack. | |
23 | + * Return | |
24 | + * 0 => % hack not present. | |
25 | + * -1 => syntax error or alloc fail. | |
26 | + * 1 transofrmed value returned. | |
27 | + */ | |
28 | +static int decode_percent_hack(const char *name, char **key) | |
29 | +{ | |
30 | + const char *tmp; | |
31 | + char *ptr, *new; | |
32 | + | |
33 | + if (!key) | |
34 | + return -1; | |
35 | + | |
36 | + *key = NULL; | |
37 | + | |
38 | + tmp = name; | |
39 | + while (*tmp && *tmp != '%' && *tmp != '[' && *tmp != ']') | |
40 | + tmp++; | |
41 | + if (!*tmp) | |
42 | + return 0; | |
43 | + | |
44 | + tmp = name; | |
45 | + while (*tmp) { | |
46 | + if (*tmp == '%') { | |
47 | + tmp++; | |
48 | + if (!*tmp) | |
49 | + return -1; | |
50 | + if (*tmp != '[') | |
51 | + continue; | |
52 | + tmp++; | |
53 | + while (*tmp && *tmp != ']') { | |
54 | + if (*tmp == '%') | |
55 | + tmp++; | |
56 | + tmp++; | |
57 | + } | |
58 | + if (!tmp) | |
59 | + return -1; | |
60 | + } | |
61 | + tmp++; | |
62 | + } | |
63 | + | |
64 | + new = malloc(strlen(name) + 1); | |
65 | + if (!new) | |
66 | + return -1; | |
67 | + | |
68 | + ptr = new; | |
69 | + tmp = name; | |
70 | + while (*tmp) { | |
71 | + if (*tmp == '%' || *tmp == '[' || *tmp == ']') { | |
72 | + tmp++; | |
73 | + if (*tmp && *tmp != '%') | |
74 | + continue; | |
75 | + } | |
76 | + *ptr++ = *tmp++; | |
77 | + } | |
78 | + *ptr = '\0'; | |
79 | + | |
80 | + *key = new; | |
81 | + | |
82 | + return strlen(new); | |
83 | +} | |
84 | + | |
85 | +static int encode_percent_hack(const char *name, char **key, unsigned int use_class) | |
86 | +{ | |
87 | + const char *tmp; | |
88 | + unsigned int len = 0; | |
89 | + char *ptr, *new; | |
90 | + | |
91 | + if (!key) | |
92 | + return -1; | |
93 | + | |
94 | + *key = NULL; | |
95 | + | |
96 | + tmp = name; | |
97 | + while (*tmp) { | |
98 | + if (*tmp == '%') | |
99 | + len++; | |
100 | + else if (isupper(*tmp)) { | |
101 | + tmp++; | |
102 | + len++; | |
103 | + if (!use_class) | |
104 | + len++; | |
105 | + else { | |
106 | + if (*tmp && isupper(*tmp)) | |
107 | + len += 2; | |
108 | + else | |
109 | + return 0; | |
110 | + while (*tmp && isupper(*tmp)) { | |
111 | + len++; | |
112 | + tmp++; | |
113 | + } | |
114 | + } | |
115 | + continue; | |
116 | + } | |
117 | + len++; | |
118 | + tmp++; | |
119 | + } | |
120 | + if (len == strlen(name)) | |
121 | + return 0; | |
122 | + | |
123 | + new = malloc(len + 1); | |
124 | + if (!new) | |
125 | + return -1; | |
126 | + | |
127 | + ptr = new; | |
128 | + tmp = name; | |
129 | + while (*tmp) { | |
130 | + if (*tmp == '%') | |
131 | + *ptr++ = '%'; | |
132 | + else if (isupper(*tmp)) { | |
133 | + char next = *tmp++; | |
134 | + *ptr++ = '%'; | |
135 | + if (*tmp && (!isupper(*tmp) || !use_class)) | |
136 | + *ptr++ = next; | |
137 | + else { | |
138 | + *ptr++ = '['; | |
139 | + *ptr++ = next; | |
140 | + while (*tmp && isupper(*tmp)) | |
141 | + *ptr++ = *tmp++; | |
142 | + *ptr++ = ']'; | |
143 | + } | |
144 | + continue; | |
145 | + } | |
146 | + *ptr++ = *tmp++; | |
147 | + } | |
148 | + *ptr = '\0'; | |
149 | + | |
150 | + *key = new; | |
151 | + | |
152 | + return strlen(new); | |
153 | +} | |
154 | + | |
155 | static int read_one_map(struct autofs_point *ap, | |
156 | struct lookup_context *ctxt, | |
157 | time_t age, int *result_ldap) | |
158 | @@ -1518,7 +1652,7 @@ static int read_one_map(struct autofs_point *ap, | |
159 | * people using older schemas that allow '*' as a key | |
160 | * value. Another case where there can be multiple key | |
161 | * values is when people have used the "%" hack to specify | |
162 | - * case matching ctriteria in a caase insensitive attribute. | |
163 | + * case matching ctriteria in a case insensitive attribute. | |
164 | */ | |
165 | count = ldap_count_values_len(bvKey); | |
166 | if (count > 1) { | |
167 | @@ -1647,9 +1781,30 @@ static int read_one_map(struct autofs_point *ap, | |
168 | *k_val = '*'; | |
169 | } | |
170 | ||
171 | - s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt); | |
172 | - if (!s_key) | |
173 | - goto next; | |
174 | + if (strcasecmp(class, "nisObject")) { | |
175 | + s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt); | |
176 | + if (!s_key) | |
177 | + goto next; | |
178 | + } else { | |
179 | + char *dec_key; | |
180 | + int dec_len = decode_percent_hack(k_val, &dec_key); | |
181 | + | |
182 | + if (dec_len < 0) { | |
183 | + crit(ap->logopt, | |
184 | + "could not use percent hack to decode key %s", | |
185 | + k_val); | |
186 | + goto next; | |
187 | + } | |
188 | + | |
189 | + if (dec_len == 0) | |
190 | + s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt); | |
191 | + else { | |
192 | + s_key = sanitize_path(dec_key, dec_len, ap->type, ap->logopt); | |
193 | + free(dec_key); | |
194 | + } | |
195 | + if (!s_key) | |
196 | + goto next; | |
197 | + } | |
198 | ||
199 | cache_writelock(mc); | |
200 | cache_update(mc, source, s_key, mapent, age); | |
201 | @@ -1712,6 +1867,8 @@ static int lookup_one(struct autofs_point *ap, | |
202 | char *query; | |
203 | LDAPMessage *result, *e; | |
204 | char *class, *info, *entry; | |
205 | + char *enc_key1, *enc_key2; | |
206 | + int enc_len1 = 0, enc_len2 = 0; | |
207 | struct berval **bvKey; | |
208 | struct berval **bvValues; | |
209 | char *attrs[3]; | |
210 | @@ -1742,14 +1899,38 @@ static int lookup_one(struct autofs_point *ap, | |
211 | ||
212 | if (*qKey == '*' && qKey_len == 1) | |
213 | *qKey = '/'; | |
214 | + else if (!strcasecmp(class, "nisObject")) { | |
215 | + enc_len1 = encode_percent_hack(qKey, &enc_key1, 0); | |
216 | + if (enc_len1 < 0) { | |
217 | + crit(ap->logopt, | |
218 | + "could not use percent hack encode key %s", | |
219 | + qKey); | |
220 | + return CHE_FAIL; | |
221 | + } | |
222 | + if (enc_len1 != 0) { | |
223 | + enc_len2 = encode_percent_hack(qKey, &enc_key2, 1); | |
224 | + if (enc_len2 < 0) { | |
225 | + crit(ap->logopt, | |
226 | + "could not use percent hack encode key %s", | |
227 | + qKey); | |
228 | + return CHE_FAIL; | |
229 | + } | |
230 | + } | |
231 | + } | |
232 | ||
233 | /* Build a query string. */ | |
234 | l = strlen(class) + 3*strlen(entry) + strlen(qKey) + 35; | |
235 | + if (enc_len1) | |
236 | + l += 2*strlen(entry) + enc_len1 + enc_len2 + 6; | |
237 | ||
238 | query = alloca(l); | |
239 | if (query == NULL) { | |
240 | char *estr = strerror_r(errno, buf, MAX_ERR_BUF); | |
241 | crit(ap->logopt, MODPREFIX "malloc: %s", estr); | |
242 | + if (enc_len1) { | |
243 | + free(enc_key1); | |
244 | + free(enc_key2); | |
245 | + } | |
246 | return CHE_FAIL; | |
247 | } | |
248 | ||
249 | @@ -1757,8 +1938,27 @@ static int lookup_one(struct autofs_point *ap, | |
250 | * Look for an entry in class under ctxt-base | |
251 | * whose entry is equal to qKey. | |
252 | */ | |
253 | - ql = sprintf(query, | |
254 | - "(&(objectclass=%s)(|(%s=%s)(%s=/)(%s=\\2A)))", class, entry, qKey, entry, entry); | |
255 | + if (!enc_len1) { | |
256 | + ql = sprintf(query, | |
257 | + "(&(objectclass=%s)(|(%s=%s)(%s=/)(%s=\\2A)))", | |
258 | + class, entry, qKey, entry, entry); | |
259 | + } else { | |
260 | + if (enc_len2) { | |
261 | + ql = sprintf(query, | |
262 | + "(&(objectclass=%s)" | |
263 | + "(|(%s=%s)(%s=%s)(%s=%s)(%s=/)(%s=\\2A)))", | |
264 | + class, entry, qKey, | |
265 | + entry, enc_key1, entry, enc_key2, entry, entry); | |
266 | + free(enc_key1); | |
267 | + free(enc_key2); | |
268 | + } else { | |
269 | + ql = sprintf(query, | |
270 | + "(&(objectclass=%s)" | |
271 | + "(|(%s=%s)(%s=%s)(%s=/)(%s=\\2A)))", | |
272 | + class, entry, qKey, entry, enc_key1, entry, entry); | |
273 | + free(enc_key1); | |
274 | + } | |
275 | + } | |
276 | if (ql >= l) { | |
277 | error(ap->logopt, | |
278 | MODPREFIX "error forming query string"); | |
279 | @@ -1934,9 +2134,30 @@ static int lookup_one(struct autofs_point *ap, | |
280 | goto next; | |
281 | } | |
282 | ||
283 | - s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt); | |
284 | - if (!s_key) | |
285 | - goto next; | |
286 | + if (strcasecmp(class, "nisObject")) { | |
287 | + s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt); | |
288 | + if (!s_key) | |
289 | + goto next; | |
290 | + } else { | |
291 | + char *dec_key; | |
292 | + int dec_len = decode_percent_hack(k_val, &dec_key); | |
293 | + | |
294 | + if (dec_len < 0) { | |
295 | + crit(ap->logopt, | |
296 | + "could not use percent hack to decode key %s", | |
297 | + k_val); | |
298 | + goto next; | |
299 | + } | |
300 | + | |
301 | + if (dec_len == 0) | |
302 | + s_key = sanitize_path(k_val, k_len, ap->type, ap->logopt); | |
303 | + else { | |
304 | + s_key = sanitize_path(dec_key, dec_len, ap->type, ap->logopt); | |
305 | + free(dec_key); | |
306 | + } | |
307 | + if (!s_key) | |
308 | + goto next; | |
309 | + } | |
310 | ||
311 | cache_writelock(mc); | |
312 | ret = cache_update(mc, source, s_key, mapent, age); |