]> 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                                 rs->sr_err = backend_group( op, NULL, &op->o_req_ndn,
68                                         &op->oq_compare.rs_ava->aa_value, NULL, ap->ap_uri );
69                                 op->o_do_not_cache = cache;
70                                 if ( rs->sr_err == LDAP_SUCCESS )
71                                         rs->sr_err = LDAP_COMPARE_TRUE;
72                                 break;
73                         }
74                 }
75         }
76         /* Default is to just fall through to the normal processing */
77         return SLAP_CB_CONTINUE;
78 }
79
80 static int dyngroup_config(
81     BackendDB   *be,
82     const char  *fname,
83     int         lineno,
84     int         argc,
85     char        **argv
86 )
87 {
88         slap_overinst *on = (slap_overinst *) be->bd_info;
89         adpair ap = { NULL, NULL, NULL }, *a2;
90
91         if ( strcasecmp( argv[0], "attrpair" ) == 0 ) {
92                 const char *text;
93                 if ( argc != 3 ) {
94                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
95                                 "attribute description missing in "
96                                 "\"attrpair <member-attribute> <URL-attribute>\" line.\n",
97                                 fname, lineno, 0 );
98                 return( 1 );
99                 }
100                 if ( slap_str2ad( argv[1], &ap.ap_mem, &text ) ) {
101                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
102                                 "attribute description unknown \"attrpair\" line: %s.\n",
103                                 fname, lineno, text );
104                         return( 1 );
105                 }
106                 if ( slap_str2ad( argv[2], &ap.ap_uri, &text ) ) {
107                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
108                                 "attribute description unknown \"attrpair\" line: %s.\n",
109                                 fname, lineno, text );
110                         return( 1 );
111                 }
112                 /* The on->on_bi.bi_private pointer can be used for
113                  * anything this instance of the overlay needs.
114                  */
115
116                 a2 = ch_malloc( sizeof(adpair) );
117                 a2->ap_next = on->on_bi.bi_private;
118                 a2->ap_mem = ap.ap_mem;
119                 a2->ap_uri = ap.ap_uri;
120                 on->on_bi.bi_private = a2;
121         } else {
122                 return SLAP_CONF_UNKNOWN;
123         }
124         return 0;
125 }
126
127 static int
128 dyngroup_close(
129         BackendDB *be
130 )
131 {
132         slap_overinst *on = (slap_overinst *) be->bd_info;
133         adpair *ap, *a2;
134
135         for ( ap = on->on_bi.bi_private; ap; ap = a2 ) {
136                 a2 = ap->ap_next;
137                 ch_free( ap );
138         }
139         return 0;
140 }
141
142 static slap_overinst dyngroup;
143
144 /* This overlay is set up for dynamic loading via moduleload. For static
145  * configuration, you'll need to arrange for the slap_overinst to be
146  * initialized and registered by some other function inside slapd.
147  */
148
149 int dyngroup_init() {
150         dyngroup.on_bi.bi_type = "dyngroup";
151         dyngroup.on_bi.bi_db_config = dyngroup_config;
152         dyngroup.on_bi.bi_db_close = dyngroup_close;
153         dyngroup.on_response = dyngroup_response;
154
155         return overlay_register( &dyngroup );
156 }
157
158 #if SLAPD_OVER_DYNGROUP == SLAPD_MOD_DYNAMIC
159 int init_module(int argc, char *argv[]) {
160         return dyngroup_init();
161 }
162 #endif
163
164 #endif /* defined(SLAPD_OVER_DYNGROUP) */