]> git.sur5r.net Git - openldap/blob - servers/slapd/overlays/dyngroup.c
Revert 1.101, not appropriate
[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-2007 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 #include "config.h"
33
34 /* This overlay extends the Compare operation to detect members of a
35  * dynamic group. It has no effect on any other operations. It must
36  * be configured with a pair of attributes to trigger on, e.g.
37  *      attrpair member memberURL
38  * will cause compares on "member" to trigger a compare on "memberURL".
39  */
40
41 typedef struct adpair {
42         struct adpair *ap_next;
43         AttributeDescription *ap_mem;
44         AttributeDescription *ap_uri;
45 } adpair;
46
47 static int
48 dyngroup_response( Operation *op, SlapReply *rs )
49 {
50         slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
51         adpair *ap = on->on_bi.bi_private;
52
53         /* If we've been configured and the current response is
54          * what we're looking for...
55          */
56         if ( ap && op->o_tag == LDAP_REQ_COMPARE &&
57                 rs->sr_err == LDAP_NO_SUCH_ATTRIBUTE ) {
58
59                 for (;ap;ap=ap->ap_next) {
60                         if ( op->oq_compare.rs_ava->aa_desc == ap->ap_mem ) {
61                                 /* This compare is for one of the attributes we're
62                                  * interested in. We'll use slapd's existing dyngroup
63                                  * evaluator to get the answer we want.
64                                  */
65                                 int cache = op->o_do_not_cache;
66                                 
67                                 op->o_do_not_cache = 1;
68                                 rs->sr_err = backend_group( op, NULL, &op->o_req_ndn,
69                                         &op->oq_compare.rs_ava->aa_value, NULL, ap->ap_uri );
70                                 op->o_do_not_cache = cache;
71                                 switch ( rs->sr_err ) {
72                                 case LDAP_SUCCESS:
73                                         rs->sr_err = LDAP_COMPARE_TRUE;
74                                         break;
75
76                                 case LDAP_NO_SUCH_OBJECT:
77                                         rs->sr_err = LDAP_COMPARE_FALSE;
78                                         break;
79                                 }
80                                 break;
81                         }
82                 }
83         }
84         /* Default is to just fall through to the normal processing */
85         return SLAP_CB_CONTINUE;
86 }
87
88 static int dyngroup_config(
89     BackendDB   *be,
90     const char  *fname,
91     int         lineno,
92     int         argc,
93     char        **argv
94 )
95 {
96         slap_overinst *on = (slap_overinst *) be->bd_info;
97         adpair ap = { NULL, NULL, NULL }, *a2;
98
99         if ( strcasecmp( argv[0], "attrpair" ) == 0 ) {
100                 const char *text;
101                 if ( argc != 3 ) {
102                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
103                                 "attribute description missing in "
104                                 "\"attrpair <member-attribute> <URL-attribute>\" line.\n",
105                                 fname, lineno, 0 );
106                 return( 1 );
107                 }
108                 if ( slap_str2ad( argv[1], &ap.ap_mem, &text ) ) {
109                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
110                                 "attribute description unknown \"attrpair\" line: %s.\n",
111                                 fname, lineno, text );
112                         return( 1 );
113                 }
114                 if ( slap_str2ad( argv[2], &ap.ap_uri, &text ) ) {
115                         Debug( LDAP_DEBUG_ANY, "%s: line %d: "
116                                 "attribute description unknown \"attrpair\" line: %s.\n",
117                                 fname, lineno, text );
118                         return( 1 );
119                 }
120                 /* The on->on_bi.bi_private pointer can be used for
121                  * anything this instance of the overlay needs.
122                  */
123
124                 a2 = ch_malloc( sizeof(adpair) );
125                 a2->ap_next = on->on_bi.bi_private;
126                 a2->ap_mem = ap.ap_mem;
127                 a2->ap_uri = ap.ap_uri;
128                 on->on_bi.bi_private = a2;
129         } else {
130                 return SLAP_CONF_UNKNOWN;
131         }
132         return 0;
133 }
134
135 static int
136 dyngroup_close(
137         BackendDB *be,
138         ConfigArgs *ca
139 )
140 {
141         slap_overinst *on = (slap_overinst *) be->bd_info;
142         adpair *ap, *a2;
143
144         for ( ap = on->on_bi.bi_private; ap; ap = a2 ) {
145                 a2 = ap->ap_next;
146                 ch_free( ap );
147         }
148         return 0;
149 }
150
151 static slap_overinst dyngroup;
152
153 /* This overlay is set up for dynamic loading via moduleload. For static
154  * configuration, you'll need to arrange for the slap_overinst to be
155  * initialized and registered by some other function inside slapd.
156  */
157
158 int dyngroup_initialize() {
159         dyngroup.on_bi.bi_type = "dyngroup";
160         dyngroup.on_bi.bi_db_config = dyngroup_config;
161         dyngroup.on_bi.bi_db_close = dyngroup_close;
162         dyngroup.on_response = dyngroup_response;
163
164         return overlay_register( &dyngroup );
165 }
166
167 #if SLAPD_OVER_DYNGROUP == SLAPD_MOD_DYNAMIC
168 int
169 init_module( int argc, char *argv[] )
170 {
171         return dyngroup_initialize();
172 }
173 #endif
174
175 #endif /* defined(SLAPD_OVER_DYNGROUP) */