1
/* dyngroup.c - Demonstration of overlay code */
2
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/dyngroup.c,v 1.10.2.3 2008/02/11 23:26:48 kurt Exp $ */
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5
* Copyright 2003-2008 The OpenLDAP Foundation.
6
* Copyright 2003 by Howard Chu.
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted only as authorized by the OpenLDAP
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>.
18
* This work was initially developed by Howard Chu for inclusion in
24
#ifdef SLAPD_OVER_DYNGROUP
28
#include <ac/string.h>
29
#include <ac/socket.h>
35
/* This overlay extends the Compare operation to detect members of a
36
* dynamic group. It has no effect on any other operations. It must
37
* be configured with a pair of attributes to trigger on, e.g.
38
* attrpair member memberURL
39
* will cause compares on "member" to trigger a compare on "memberURL".
42
typedef struct adpair {
43
struct adpair *ap_next;
44
AttributeDescription *ap_mem;
45
AttributeDescription *ap_uri;
48
static int dgroup_cf( ConfigArgs *c )
50
slap_overinst *on = (slap_overinst *)c->bi;
54
case SLAP_CONFIG_EMIT:
57
for ( ap = on->on_bi.bi_private; ap; ap = ap->ap_next ) {
60
bv.bv_len = ap->ap_mem->ad_cname.bv_len + 1 +
61
ap->ap_uri->ad_cname.bv_len;
62
bv.bv_val = ch_malloc( bv.bv_len + 1 );
63
ptr = lutil_strcopy( bv.bv_val, ap->ap_mem->ad_cname.bv_val );
65
strcpy( ptr, ap->ap_uri->ad_cname.bv_val );
66
ber_bvarray_add( &c->rvalue_vals, &bv );
72
if ( c->valx == -1 ) {
74
while (( ap = on->on_bi.bi_private )) {
75
on->on_bi.bi_private = ap->ap_next;
81
app = (adpair **)&on->on_bi.bi_private;
82
for (i=0; i<=c->valx; i++, app = &ap->ap_next) {
93
adpair ap = { NULL, NULL, NULL }, *a2;
95
if ( slap_str2ad( c->argv[1], &ap.ap_mem, &text ) ) {
96
snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s attribute description unknown: \"%s\"",
97
c->argv[0], c->argv[1] );
98
Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
99
"%s: %s\n", c->log, c->cr_msg, 0 );
102
if ( slap_str2ad( c->argv[2], &ap.ap_uri, &text ) ) {
103
snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s attribute description unknown: \"%s\"",
104
c->argv[0], c->argv[2] );
105
Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
106
"%s: %s\n", c->log, c->cr_msg, 0 );
109
/* The on->on_bi.bi_private pointer can be used for
110
* anything this instance of the overlay needs.
112
a2 = ch_malloc( sizeof(adpair) );
113
a2->ap_next = on->on_bi.bi_private;
114
a2->ap_mem = ap.ap_mem;
115
a2->ap_uri = ap.ap_uri;
116
on->on_bi.bi_private = a2;
123
static ConfigTable dgroupcfg[] = {
124
{ "attrpair", "member-attribute> <URL-attribute", 3, 3, 0,
125
ARG_MAGIC, dgroup_cf,
126
"( OLcfgOvAt:17.1 NAME 'olcDGAttrPair' "
127
"DESC 'Member and MemberURL attribute pair' "
128
"SYNTAX OMsDirectoryString )", NULL, NULL },
129
{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
132
static ConfigOCs dgroupocs[] = {
133
{ "( OLcfgOvOc:17.1 "
134
"NAME 'olcDGConfig' "
135
"DESC 'Dynamic Group configuration' "
136
"SUP olcOverlayConfig "
137
"MAY olcDGAttrPair )",
138
Cft_Overlay, dgroupcfg },
143
dyngroup_response( Operation *op, SlapReply *rs )
145
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
146
adpair *ap = on->on_bi.bi_private;
148
/* If we've been configured and the current response is
149
* what we're looking for...
151
if ( ap && op->o_tag == LDAP_REQ_COMPARE &&
152
rs->sr_err == LDAP_NO_SUCH_ATTRIBUTE ) {
154
for (;ap;ap=ap->ap_next) {
155
if ( op->oq_compare.rs_ava->aa_desc == ap->ap_mem ) {
156
/* This compare is for one of the attributes we're
157
* interested in. We'll use slapd's existing dyngroup
158
* evaluator to get the answer we want.
160
int cache = op->o_do_not_cache;
162
op->o_do_not_cache = 1;
163
rs->sr_err = backend_group( op, NULL, &op->o_req_ndn,
164
&op->oq_compare.rs_ava->aa_value, NULL, ap->ap_uri );
165
op->o_do_not_cache = cache;
166
switch ( rs->sr_err ) {
168
rs->sr_err = LDAP_COMPARE_TRUE;
171
case LDAP_NO_SUCH_OBJECT:
172
rs->sr_err = LDAP_COMPARE_FALSE;
179
/* Default is to just fall through to the normal processing */
180
return SLAP_CB_CONTINUE;
189
slap_overinst *on = (slap_overinst *) be->bd_info;
192
for ( ap = on->on_bi.bi_private; ap; ap = a2 ) {
199
static slap_overinst dyngroup;
201
/* This overlay is set up for dynamic loading via moduleload. For static
202
* configuration, you'll need to arrange for the slap_overinst to be
203
* initialized and registered by some other function inside slapd.
206
int dyngroup_initialize() {
209
dyngroup.on_bi.bi_type = "dyngroup";
210
dyngroup.on_bi.bi_db_close = dyngroup_close;
211
dyngroup.on_response = dyngroup_response;
213
dyngroup.on_bi.bi_cf_ocs = dgroupocs;
214
code = config_register_schema( dgroupcfg, dgroupocs );
215
if ( code ) return code;
217
return overlay_register( &dyngroup );
220
#if SLAPD_OVER_DYNGROUP == SLAPD_MOD_DYNAMIC
222
init_module( int argc, char *argv[] )
224
return dyngroup_initialize();
228
#endif /* defined(SLAPD_OVER_DYNGROUP) */