]> git.sur5r.net Git - openldap/blob - servers/slapd/overlays/dyngroup.c
Sync with HEAD
[openldap] / servers / slapd / overlays / dyngroup.c
1 /* dyngroup.c - Demonstration of overlay code */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2003-2005 The OpenLDAP Foundation.
6  * Copyright 2003 by Howard Chu.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
13  * A copy of this license is available in the file LICENSE in the
14  * top-level directory of the distribution or, alternatively, at
15  * <http://www.OpenLDAP.org/license.html>.
16  */
17 /* ACKNOWLEDGEMENTS:
18  * This work was initially developed by Howard Chu for inclusion in
19  * OpenLDAP Software.
20  */
21
22 #include "portable.h"
23
24 #ifdef SLAPD_OVER_DYNGROUP
25
26 #include <stdio.h>
27
28 #include <ac/string.h>
29 #include <ac/socket.h>
30
31 #include "slap.h"
32
33 /* This overlay extends the Compare operation to detect members of a
34  * dynamic group. It has no effect on any other operations. It must
35  * be configured with a pair of attributes to trigger on, e.g.
36  *      attrpair member memberURL
37  * will cause compares on "member" to trigger a compare on "memberURL".
38  */
39
40 typedef struct adpair {
41         struct adpair *ap_next;
42         AttributeDescription *ap_mem;
43         AttributeDescription *ap_uri;
44 } adpair;
45
46 static int
47 dyngroup_response( Operation *op, SlapReply *rs )
48 {
49         slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
50         adpair *ap = on->on_bi.bi_private;
51
52         /* If we've been configured and the current response is
53          * what we're looking for...
54          */
55         if ( ap && op->o_tag == LDAP_REQ_COMPARE &&
56                 rs->sr_err == LDAP_NO_SUCH_ATTRIBUTE ) {
57
58                 for (;ap;ap=ap->ap_next) {
59                         if ( op->oq_compare.rs_ava->aa_desc == ap->ap_mem ) {
60                                 /* This compare is for one of the attributes we're
61                                  * interested in. We'll use slapd's existing dyngroup
62                                  * evaluator to get the answer we want.
63                                  */
64                                 int cache = op->o_do_not_cache;
65                                 
66                                 op->o_do_not_cache = 1;
67                                 if ( backend_group( op, NULL, &op->o_req_ndn,
68                                         &op->oq_compare.rs_ava->aa_value, NULL, ap->ap_uri ) == 0 )
69                                         rs->sr_err = LDAP_COMPARE_TRUE;
70                                 op->o_do_not_cache = cache;
71                                 break;
72                         }
73                 }
74         }
75         /* Default is to just fall through to the normal processing */
76         return SLAP_CB_CONTINUE;
77 }
78
79 static int dyngroup_config(
80     BackendDB   *be,
81     const char  *fname,
82     int         lineno,
83     int         argc,
84     char        **argv
85 )
86 {
87         slap_overinst *on = (slap_overinst *) be->bd_info;
88         adpair ap = { NULL, NULL, NULL }, *a2;
89
90         if ( strcasecmp( argv[0], "attrpair" ) == 0 ) {
91                 const char *text;
92                 if ( argc != 3 ) {
93                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
94                                 "attribute description missing in "
95                                 "\"attrpair <member-attribute> <URL-attribute>\" line.\n",
96                                 fname, lineno, 0 );
97                 return( 1 );
98                 }
99                 if ( slap_str2ad( argv[1], &ap.ap_mem, &text ) ) {
100                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
101                                 "attribute description unknown \"attrpair\" line: %s.\n",
102                                 fname, lineno, text );
103                         return( 1 );
104                 }
105                 if ( slap_str2ad( argv[2], &ap.ap_uri, &text ) ) {
106                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
107                                 "attribute description unknown \"attrpair\" line: %s.\n",
108                                 fname, lineno, text );
109                         return( 1 );
110                 }
111                 /* The on->on_bi.bi_private pointer can be used for
112                  * anything this instance of the overlay needs.
113                  */
114
115                 a2 = ch_malloc( sizeof(adpair) );
116                 a2->ap_next = on->on_bi.bi_private;
117                 a2->ap_mem = ap.ap_mem;
118                 a2->ap_uri = ap.ap_uri;
119                 on->on_bi.bi_private = a2;
120         } else {
121                 return SLAP_CONF_UNKNOWN;
122         }
123         return 0;
124 }
125
126 static int
127 dyngroup_close(
128         BackendDB *be
129 )
130 {
131         slap_overinst *on = (slap_overinst *) be->bd_info;
132         adpair *ap, *a2;
133
134         for ( ap = on->on_bi.bi_private; ap; ap = a2 ) {
135                 a2 = ap->ap_next;
136                 ch_free( ap );
137         }
138         return 0;
139 }
140
141 static slap_overinst dyngroup;
142
143 /* This overlay is set up for dynamic loading via moduleload. For static
144  * configuration, you'll need to arrange for the slap_overinst to be
145  * initialized and registered by some other function inside slapd.
146  */
147
148 int dyngroup_init() {
149         dyngroup.on_bi.bi_type = "dyngroup";
150         dyngroup.on_bi.bi_db_config = dyngroup_config;
151         dyngroup.on_bi.bi_db_close = dyngroup_close;
152         dyngroup.on_response = dyngroup_response;
153
154         return overlay_register( &dyngroup );
155 }
156
157 #if SLAPD_OVER_DYNGROUP == SLAPD_MOD_DYNAMIC
158 int init_module(int argc, char *argv[]) {
159         return dyngroup_init();
160 }
161 #endif
162
163 #endif /* defined(SLAPD_OVER_DYNGROUP) */