]> git.pld-linux.org Git - packages/autofs.git/blob - autofs-5.0.2-add-ldap-schema-discovery.patch
- 5.0.3 with few official patches. ldap fixes needed
[packages/autofs.git] / autofs-5.0.2-add-ldap-schema-discovery.patch
1 diff --git a/CHANGELOG b/CHANGELOG
2 index 92013ce..c36017a 100644
3 --- a/CHANGELOG
4 +++ b/CHANGELOG
5 @@ -19,6 +19,7 @@
6  - fix "nosymlink" option handling and add desription to man page.
7  - fix don't fail on empty master map.
8  - if there's no "automount" entry in nsswitch.conf use "files" source.
9 +- add LDAP schema discovery if no schema is configured.
10  
11  18/06/2007 autofs-5.0.2
12  -----------------------
13 diff --git a/include/defaults.h b/include/defaults.h
14 index ef58467..9aec11a 100644
15 --- a/include/defaults.h
16 +++ b/include/defaults.h
17 @@ -43,11 +43,8 @@ unsigned int defaults_get_timeout(void);
18  unsigned int defaults_get_browse_mode(void);
19  unsigned int defaults_get_logging(void);
20  const char *defaults_get_ldap_server(void);
21 -const char *defaults_get_map_obj_class(void);
22 -const char *defaults_get_entry_obj_class(void);
23 -const char *defaults_get_map_attr(void);
24 -const char *defaults_get_entry_attr(void);
25 -const char *defaults_get_value_attr(void);
26 +struct ldap_schema *defaults_get_default_schema(void);
27 +struct ldap_schema *defaults_get_schema(void);
28  unsigned int defaults_get_append_options(void);
29  const char *defaults_get_auth_conf_file(void);
30  
31 diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
32 index 0a9deca..1378b9e 100644
33 --- a/include/lookup_ldap.h
34 +++ b/include/lookup_ldap.h
35 @@ -10,6 +10,14 @@
36  #include <krb5.h>
37  #endif
38  
39 +struct ldap_schema {
40 +       char *map_class;
41 +       char *map_attr;
42 +       char *entry_class;
43 +       char *entry_attr;
44 +       char *value_attr;
45 +};
46 +
47  struct lookup_context {
48         char *mapname;
49  
50 @@ -22,11 +30,7 @@ struct lookup_context {
51         int version;
52  
53         /* LDAP lookup configuration */
54 -       char *map_obj_class;
55 -       char *entry_obj_class;
56 -       char *map_attr;
57 -       char *entry_attr;
58 -       char *value_attr;
59 +       struct ldap_schema *schema;
60  
61         /* TLS and SASL authentication information */
62         char        *auth_conf;
63 diff --git a/lib/defaults.c b/lib/defaults.c
64 index 4b4acba..b146f13 100644
65 --- a/lib/defaults.c
66 +++ b/lib/defaults.c
67 @@ -18,6 +18,7 @@
68  #include <string.h>
69  
70  #include "defaults.h"
71 +#include "lookup_ldap.h"
72  #include "log.h"
73  
74  #define DEFAULTS_CONFIG_FILE           AUTOFS_CONF_DIR "/autofs"
75 @@ -41,16 +42,8 @@
76  #define ENV_AUTH_CONF_FILE             "AUTH_CONF_FILE"
77  
78  static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME;
79 -
80 -static const char *default_ldap_server         = DEFAULT_LDAP_SERVER;
81 -
82 -static const char *default_map_obj_class       = DEFAULT_MAP_OBJ_CLASS;
83 -static const char *default_entry_obj_class     = DEFAULT_ENTRY_OBJ_CLASS;
84 -static const char *default_map_attr            = DEFAULT_MAP_ATTR;
85 -static const char *default_entry_attr          = DEFAULT_ENTRY_ATTR;
86 -static const char *default_value_attr          = DEFAULT_VALUE_ATTR;
87 -
88 -static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE;
89 +static const char *default_ldap_server    = DEFAULT_LDAP_SERVER;
90 +static const char *default_auth_conf_file  = DEFAULT_AUTH_CONF_FILE;
91  
92  static char *get_env_string(const char *name)
93  {
94 @@ -285,59 +278,120 @@ const char *defaults_get_ldap_server(void)
95         return (const char *) server;
96  }
97  
98 -const char *defaults_get_map_obj_class(void)
99 +struct ldap_schema *defaults_get_default_schema(void)
100  {
101 -       char *moc;
102 +       struct ldap_schema *schema;
103 +       char *mc, *ma, *ec, *ea, *va;
104  
105 -       moc = get_env_string(ENV_NAME_MAP_OBJ_CLASS);
106 -       if (!moc)
107 -               return strdup(default_map_obj_class);
108 +       mc = strdup(DEFAULT_MAP_OBJ_CLASS);
109 +       if (!mc)
110 +               return NULL;
111  
112 -       return (const char *) moc;
113 -}
114 +       ma = strdup(DEFAULT_MAP_ATTR);
115 +       if (!ma) {
116 +               free(mc);
117 +               return NULL;
118 +       }
119  
120 -const char *defaults_get_entry_obj_class(void)
121 -{
122 -       char *eoc;
123 +       ec = strdup(DEFAULT_ENTRY_OBJ_CLASS);
124 +       if (!ec) {
125 +               free(mc);
126 +               free(ma);
127 +               return NULL;
128 +       }
129  
130 -       eoc = get_env_string(ENV_NAME_ENTRY_OBJ_CLASS);
131 -       if (!eoc)
132 -               return strdup(default_entry_obj_class);
133 +       ea = strdup(DEFAULT_ENTRY_ATTR);
134 +       if (!ea) {
135 +               free(mc);
136 +               free(ma);
137 +               free(ec);
138 +               return NULL;
139 +       }
140  
141 -       return (const char *) eoc;
142 -}
143 +       va = strdup(DEFAULT_VALUE_ATTR);
144 +       if (!va) {
145 +               free(mc);
146 +               free(ma);
147 +               free(ec);
148 +               free(ea);
149 +               return NULL;
150 +       }
151  
152 -const char *defaults_get_map_attr(void)
153 -{
154 -       char *ma;
155 +       schema = malloc(sizeof(struct ldap_schema));
156 +       if (!schema) {
157 +               free(mc);
158 +               free(ma);
159 +               free(ec);
160 +               free(ea);
161 +               free(va);
162 +               return NULL;
163 +       }
164  
165 -       ma = get_env_string(ENV_NAME_MAP_ATTR);
166 -       if (!ma)
167 -               return strdup(default_map_attr);
168 +       schema->map_class = mc;
169 +       schema->map_attr = ma;
170 +       schema->entry_class = ec;
171 +       schema->entry_attr = ea;
172 +       schema->value_attr = va;
173  
174 -       return (const char *) ma;
175 +       return schema;
176  }
177  
178 -const char *defaults_get_entry_attr(void)
179 +struct ldap_schema *defaults_get_schema(void)
180  {
181 -       char *ea;
182 +       struct ldap_schema *schema;
183 +       char *mc, *ma, *ec, *ea, *va;
184  
185 -       ea = get_env_string(ENV_NAME_ENTRY_ATTR);
186 -       if (!ea)
187 -               return strdup(default_entry_attr);
188 +       mc = get_env_string(ENV_NAME_MAP_OBJ_CLASS);
189 +       if (!mc)
190 +               return NULL;
191  
192 -       return (const char *) ea;
193 -}
194 +       ma = get_env_string(ENV_NAME_MAP_ATTR);
195 +       if (!ma) {
196 +               free(mc);
197 +               return NULL;
198 +       }
199  
200 -const char *defaults_get_value_attr(void)
201 -{
202 -       char *va;
203 +       ec = get_env_string(ENV_NAME_ENTRY_OBJ_CLASS);
204 +       if (!ec) {
205 +               free(mc);
206 +               free(ma);
207 +               return NULL;
208 +       }
209 +
210 +       ea = get_env_string(ENV_NAME_ENTRY_ATTR);
211 +       if (!ea) {
212 +               free(mc);
213 +               free(ma);
214 +               free(ec);
215 +               return NULL;
216 +       }
217  
218         va = get_env_string(ENV_NAME_VALUE_ATTR);
219 -       if (!va)
220 -               return strdup(default_value_attr);
221 +       if (!va) {
222 +               free(mc);
223 +               free(ma);
224 +               free(ec);
225 +               free(ea);
226 +               return NULL;
227 +       }
228 +
229 +       schema = malloc(sizeof(struct ldap_schema));
230 +       if (!schema) {
231 +               free(mc);
232 +               free(ma);
233 +               free(ec);
234 +               free(ea);
235 +               free(va);
236 +               return NULL;
237 +       }
238 +
239 +       schema->map_class = mc;
240 +       schema->map_attr = ma;
241 +       schema->entry_class = ec;
242 +       schema->entry_attr = ea;
243 +       schema->value_attr = va;
244  
245 -       return (const char *) va;
246 +       return schema;
247  }
248  
249  unsigned int defaults_get_append_options(void)
250 diff --git a/man/auto.master.5.in b/man/auto.master.5.in
251 index 69c796e..249c9a7 100644
252 --- a/man/auto.master.5.in
253 +++ b/man/auto.master.5.in
254 @@ -191,17 +191,25 @@ The old style
255  is also understood. Alternatively, the type can be obtained from the Name Service Switch
256  configuration, in which case the map name alone must be given.
257  .P
258 -The default LDAP schema is the NIS schema described in RFC 2307.
259 -Entries in the nisMap schema are \fBnisObject\fP objects in
260 +If no schema is set in the autofs configuration then autofs will check
261 +each of the commonly used schema for a valid entry and if one is found
262 +it will used for subsequent lookups.
263 +.P
264 +There are three common schemas in use:
265 +.TP
266 +.I nisMap
267 +Entries in the \fBnisMap\fP schema are \fBnisObject\fP objects in
268  the specified subtree, where the \fBcn\fP attribute is the key
269  (the wildcard key is "/"), and the \fBnisMapEntry\fP attribute
270  contains the information used by the automounter.
271 -.P
272 -Entries in the automountMap schema are \fBautomount\fP objects in
273 -the specified subtree, where the \fBcn\fP or \fBautomountKey\fP attribute
274 -(depending on local usage) is the key (the wildcard key is "/"), and the
275 -\fBautomountInformation\fP attribute contains the information used by the
276 -automounter.
277 +.TP
278 +.I automountMap
279 +The \fBautomountMap\fP schema has two variations that differ in the attribute
280 +used for the map key. Entries in the automountMap schema are \fBautomount\fP
281 +objects in the specified subtree, where the \fBcn\fP or \fBautomountKey\fP
282 +attribute (depending on local usage) is the key (the wildcard key is "/"),
283 +and the \fBautomountInformation\fP attribute contains the information used
284 +by the automounter. Note that the \fBcn\fP attribute is case insensitive.
285  .P
286  The object classes and attributes used for accessing automount maps in
287  LDAP can be changed by setting entries in the autofs configuration
288 @@ -209,61 +217,44 @@ located in
289  .nh
290  .BR @@autofsconfdir@@/autofs .
291  .hy
292 +.TP
293 +.B NOTE:
294 +If a schema is given in the configuration then all the schema configuration
295 +values must be set, any partial schema specification will be ignored.
296  .P
297  The configuration settings available are:
298  .TP
299 -\fBMAP_OBJECT_CLASS\fP
300 -The map object class. Its Default value is "nisMap". In the
301 -.nh
302 -automountMap
303 -.hy
304 -schema this corresponds to the class
305 -.nh
306 -.BR automountMap .
307 -.hy
308 +.B MAP_OBJECT_CLASS
309 +The map object class. In the \fBnisMap\fP schema this corresponds to the class
310 +\fBnisMap\fP and in the \fBautomountMap\fP schema it corresponds to the class
311 +\fBautomountMap\fP.
312  .TP
313  .B ENTRY_OBJECT_CLASS
314 -The map entry object class. Its default value is \fBnisObject\fP.
315 -In the automountMap schema this corresponds to the class
316 -.nh
317 -.BR automount .
318 -.hy
319 +The map entry object class. In the \fBnisMap\fP schema this corresponds
320 +to the class \fBnisObject\fP and in the \fBautomountMap\fP schema it
321 +corresponds to the class \fBautomount\fP.
322  .TP
323  .B MAP_ATTRIBUTE
324  The attribute used to identify the name of the map to which this
325 -entry belongs. Its default value is
326 -.nh
327 -.BR nisMapName .
328 -.hy
329 -In the
330 -.nh
331 -automountMap
332 -.hy
333 -schema this corresponds to the attributes \fBou\fP or
334 -.nh
335 -.BR automountMapName .
336 -.hy
337 +entry belongs.  In the \fBnisMap\fP schema this corresponds to the attribute
338 +\fBnisMapName\fP and in the \fBautomountMap\fP schema it corresponds to the
339 +attribute \fBou\fP or \fBautomountMapName\fP.
340  .TP
341  .B ENTRY_ATTRIBUTE
342 -The attribute used to identify a map key. Its default value is
343 -In the
344 -.nh
345 -automountMap
346 -.hy
347 -schema this corresponds to the attribute
348 -.nh
349 -.BR automountKey .
350 -.hy
351 +The attribute used to identify a map key. In the \fBnisMap\fP schema this
352 +corresponds to the attribute \fBcn\fP and in the \fBautomountMap\fP schema
353 +it corresponds to the attribute \fBautomountKey\fP.
354  .TP
355  .B VALUE_ATTRIBUTE
356 -The attribute used to identify the value of the map entry. Its default
357 -value is
358 -.nh
359 -.BR BnisMapEntry .
360 -.hy
361 -In the automountMap schema this corresponds to the attribute
362 -.nh
363 -.BR automountInformation .
364 +The attribute used to identify the value of the map entry. In the \fBnisMap\fP
365 +schema this corresponds to the attribute \fBnisMapEntry\fP and in the \fBautomountMap\fP
366 +schema it corresponds to the attribute \fBautomountInformation\fP.
367 +.TP
368 +.B NOTE:
369 +It is essential that entries use class and attribute in a consistent
370 +manner for correct operation of autofs. For example mixing \fBcn\fP and
371 +\fBautomountKey\fP attributes in \fBautomount\fP schema map entries won't
372 +work as expected.
373  .SH LDAP AUTHENTICATION, ENCRYPTED AND CERTIFIED CONNECTIONS
374  LDAP authenticated binds, TLS encrypted connections and certification
375  may be used by setting appropriate values in the autofs authentication
376 diff --git a/man/automount.8 b/man/automount.8
377 index fc1846a..da67a5c 100644
378 --- a/man/automount.8
379 +++ b/man/automount.8
380 @@ -102,6 +102,8 @@ started they will be recoverd unless they are no longer present in
381  the map in which case they need to umounted manually.
382  .SH "SEE ALSO"
383  .BR autofs (5),
384 +.BR autofs (8),
385 +.BR auto.master (5),
386  .BR mount (8).
387  .SH BUGS
388  Don't know, I've fixed everything I know about.
389 diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
390 index a412797..d5e666b 100644
391 --- a/modules/lookup_ldap.c
392 +++ b/modules/lookup_ldap.c
393 @@ -42,6 +42,13 @@
394  
395  int lookup_version = AUTOFS_LOOKUP_VERSION;    /* Required by protocol */
396  
397 +static struct ldap_schema common_schema[] = {
398 +       {"nisMap", "nisMapName", "nisObject", "cn", "nisMapEntry"},
399 +       {"automountMap", "ou", "automount", "cn", "automountInformation"},
400 +       {"automountMap", "automountMapName", "automount", "automountKey", "automountInformation"},
401 +};
402 +static unsigned int common_schema_count = sizeof(common_schema)/sizeof(struct ldap_schema);
403 +
404  int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
405  {
406         int rv;
407 @@ -738,54 +745,15 @@ done:
408         return 1;
409  }
410  
411 -static int get_default_schema(struct lookup_context *ctxt)
412 -{
413 -       ctxt->map_obj_class = (char *) defaults_get_map_obj_class();
414 -       if (!ctxt->map_obj_class)
415 -               return 0;
416 -
417 -       ctxt->entry_obj_class = (char *) defaults_get_entry_obj_class();
418 -       if (!ctxt->entry_obj_class)
419 -               goto free_moc;
420 -
421 -       ctxt->map_attr = (char *) defaults_get_map_attr();
422 -       if (!ctxt->map_attr)
423 -               goto free_eoc;
424 -
425 -       ctxt->entry_attr = (char *) defaults_get_entry_attr();
426 -       if (!ctxt->entry_attr)
427 -               goto free_ma;
428 -
429 -       ctxt->value_attr = (char *) defaults_get_value_attr();
430 -       if (!ctxt->value_attr)
431 -               goto free_ea;
432 -
433 -       return 1;
434 -
435 -free_ea:
436 -       free(ctxt->entry_attr);
437 -free_ma:
438 -       free(ctxt->map_attr);
439 -free_eoc:
440 -       free(ctxt->entry_obj_class);
441 -free_moc:
442 -       free(ctxt->map_obj_class);
443 -
444 -       ctxt->map_obj_class = NULL;
445 -       ctxt->entry_obj_class = NULL;
446 -       ctxt->map_attr = NULL;
447 -       ctxt->entry_attr = NULL;
448 -
449 -       return 0;
450 -}
451 -
452  static void free_context(struct lookup_context *ctxt)
453  {
454 -       if (ctxt->map_obj_class) {
455 -               free(ctxt->map_obj_class);
456 -               free(ctxt->entry_obj_class);
457 -               free(ctxt->map_attr);
458 -               free(ctxt->entry_attr);
459 +       if (ctxt->schema) {
460 +               free(ctxt->schema->map_class);
461 +               free(ctxt->schema->map_attr);
462 +               free(ctxt->schema->entry_class);
463 +               free(ctxt->schema->entry_attr);
464 +               free(ctxt->schema->value_attr);
465 +               free(ctxt->schema);
466         }
467         if (ctxt->auth_conf)
468                 free(ctxt->auth_conf);
469 @@ -808,19 +776,15 @@ static void free_context(struct lookup_context *ctxt)
470         return;
471  }
472  
473 -static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt)
474 +static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key)
475  {
476         char buf[PARSE_MAX_BUF];
477         char *query, *dn;
478         LDAPMessage *result, *e;
479 -       char *class, *key;
480         char *attrs[2];
481         int scope;
482         int rv, l;
483  
484 -       class = ctxt->map_obj_class;
485 -       key = ctxt->map_attr;
486 -
487         attrs[0] = LDAP_NO_ATTRS;
488         attrs[1] = NULL;
489  
490 @@ -890,6 +854,90 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt)
491         return 1;
492  }
493  
494 +static struct ldap_schema *alloc_common_schema(struct ldap_schema *s)
495 +{
496 +       struct ldap_schema *schema;
497 +       char *mc, *ma, *ec, *ea, *va;
498 +
499 +       mc = strdup(s->map_class);
500 +       if (!mc)
501 +               return NULL;
502 +
503 +       ma = strdup(s->map_attr);
504 +       if (!ma) {
505 +               free(mc);
506 +               return NULL;
507 +       }
508 +
509 +       ec = strdup(s->entry_class);
510 +       if (!ec) {
511 +               free(mc);
512 +               free(ma);
513 +               return NULL;
514 +       }
515 +
516 +       ea = strdup(s->entry_attr);
517 +       if (!ea) {
518 +               free(mc);
519 +               free(ma);
520 +               free(ec);
521 +               return NULL;
522 +       }
523 +
524 +       va = strdup(s->value_attr);
525 +       if (!va) {
526 +               free(mc);
527 +               free(ma);
528 +               free(ec);
529 +               free(ea);
530 +               return NULL;
531 +       }
532 +
533 +       schema = malloc(sizeof(struct ldap_schema));
534 +       if (!schema) {
535 +               free(mc);
536 +               free(ma);
537 +               free(ec);
538 +               free(ea);
539 +               free(va);
540 +               return NULL;
541 +       }
542 +
543 +       schema->map_class = mc;
544 +       schema->map_attr = ma;
545 +       schema->entry_class = ec;
546 +       schema->entry_attr = ea;
547 +       schema->value_attr = va;
548 +
549 +       return schema;
550 +}
551 +
552 +static int find_query_dn(LDAP *ldap, struct lookup_context *ctxt)
553 +{
554 +       struct ldap_schema *schema;
555 +       unsigned int i;
556 +
557 +       if (ctxt->schema)
558 +               return 0;
559 +
560 +       for (i = 0; i < common_schema_count; i++) {
561 +               const char *class = common_schema[i].map_class;
562 +               const char *key = common_schema[i].map_attr;
563 +               if (get_query_dn(ldap, ctxt, class, key)) {
564 +                       schema = alloc_common_schema(&common_schema[i]);
565 +                       if (!schema) {
566 +                               error(LOGOPT_ANY,
567 +                                     MODPREFIX "failed to allocate schema");
568 +                               return 0;
569 +                       }
570 +                       ctxt->schema = schema;
571 +                       return 1;
572 +               }
573 +       }
574 +
575 +       return 0;
576 +}
577 +
578  /*
579   * This initializes a context (persistent non-global data) for queries to
580   * this module.  Return zero if we succeed.
581 @@ -926,13 +974,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
582                 return 1;
583         }
584  
585 -       /* Get default schema for queries */
586 -       if (!get_default_schema(ctxt)) {
587 -               error(LOGOPT_ANY, MODPREFIX "cannot set default schema");
588 -               free_context(ctxt);
589 -               return 1;
590 -       }
591 -
592  #ifdef WITH_SASL
593         /*
594          * Determine which authentication mechanism to use.  We sanity-
595 @@ -954,13 +995,22 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
596                 return 1;
597         }
598  
599 -       ret = get_query_dn(ldap, ctxt);
600 -       unbind_ldap_connection(ldap, ctxt);
601 -       if (!ret) {
602 -               error(LOGOPT_ANY, MODPREFIX "failed to get query dn");
603 -               free_context(ctxt);
604 -               return 1;
605 +       /*
606 +        * Get default schema for queries.
607 +        * If the schema isn't defined in the configuration then check for
608 +        * presence of a map dn in the common schemas.
609 +        */
610 +       ctxt->schema = defaults_get_schema();
611 +       if (!ctxt->schema) {
612 +               if (!find_query_dn(ldap, ctxt)) {
613 +                       unbind_ldap_connection(ldap, ctxt);
614 +                       error(LOGOPT_ANY,
615 +                             MODPREFIX "failed to find valid query dn");
616 +                       free_context(ctxt);
617 +                       return 1;
618 +               }
619         }
620 +       unbind_ldap_connection(ldap, ctxt);
621  
622         /* Open the parser, if we can. */
623         ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
624 @@ -990,9 +1040,9 @@ int lookup_read_master(struct master *master, time_t age, void *context)
625         int scope = LDAP_SCOPE_SUBTREE;
626         LDAP *ldap;
627  
628 -       class = ctxt->entry_obj_class;
629 -       entry = ctxt->entry_attr;
630 -       info = ctxt->value_attr;
631 +       class = ctxt->schema->entry_class;
632 +       entry = ctxt->schema->entry_attr;
633 +       info = ctxt->schema->value_attr;
634  
635         attrs[0] = entry;
636         attrs[1] = info;
637 @@ -1141,9 +1191,9 @@ static int read_one_map(struct autofs_point *ap,
638  
639         mc = source->mc;
640  
641 -       class = ctxt->entry_obj_class;
642 -       entry = ctxt->entry_attr;
643 -       info = ctxt->value_attr;
644 +       class = ctxt->schema->entry_class;
645 +       entry = ctxt->schema->entry_attr;
646 +       info = ctxt->schema->value_attr;
647  
648         attrs[0] = entry;
649         attrs[1] = info;
650 @@ -1438,9 +1488,9 @@ static int lookup_one(struct autofs_point *ap,
651                 return CHE_FAIL;
652         }
653  
654 -       class = ctxt->entry_obj_class;
655 -       entry = ctxt->entry_attr;
656 -       info = ctxt->value_attr;
657 +       class = ctxt->schema->entry_class;
658 +       entry = ctxt->schema->entry_attr;
659 +       info = ctxt->schema->value_attr;
660  
661         attrs[0] = entry;
662         attrs[1] = info;
This page took 0.130408 seconds and 3 git commands to generate.