Back to index

openldap  2.4.31
Classes | Defines | Typedefs | Enumerations | Functions | Variables
autogroup.c File Reference
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include "slap.h"
#include "config.h"
#include "lutil.h"

Go to the source code of this file.

Classes

struct  autogroup_filter_t
struct  autogroup_def_t
struct  autogroup_entry_t
struct  autogroup_info_t
struct  autogroup_sc_t
struct  autogroup_ga_t

Defines

#define SLAPD_MEMBEROF_ATTR   "memberOf"

Typedefs

typedef struct autogroup_filter_t autogroup_filter_t
typedef struct autogroup_def_t autogroup_def_t
typedef struct autogroup_entry_t autogroup_entry_t
typedef struct autogroup_info_t autogroup_info_t
typedef struct autogroup_sc_t autogroup_sc_t
typedef struct autogroup_ga_t autogroup_ga_t

Enumerations

enum  { AG_ATTRSET = 1, AG_MEMBER_OF_AD, AG_LAST }

Functions

static int autogroup_add_member_to_group (Operation *op, BerValue *dn, BerValue *ndn, autogroup_entry_t *age)
static int autogroup_add_member_values_to_group (Operation *op, Entry *e, autogroup_entry_t *age, AttributeDescription *attrdesc)
static int autogroup_delete_member_from_group (Operation *op, BerValue *dn, BerValue *ndn, autogroup_entry_t *age)
static int autogroup_delete_member_values_from_group (Operation *op, Entry *e, autogroup_entry_t *age, AttributeDescription *attrdesc)
static int autogroup_member_search_cb (Operation *op, SlapReply *rs)
static int autogroup_member_search_modify_cb (Operation *op, SlapReply *rs)
static int autogroup_add_members_from_filter (Operation *op, Entry *e, autogroup_entry_t *age, autogroup_filter_t *agf, int modify)
static int autogroup_add_group (Operation *op, autogroup_info_t *agi, autogroup_def_t *agd, Entry *e, BerValue *ndn, int scan, int modify)
static int autogroup_group_add_cb (Operation *op, SlapReply *rs)
static int autogroup_add_entry (Operation *op, SlapReply *rs)
static int autogroup_delete_group (autogroup_info_t *agi, autogroup_entry_t *e)
static int autogroup_delete_entry (Operation *op, SlapReply *rs)
static int autogroup_response (Operation *op, SlapReply *rs)
static int autogroup_memberOf_filter (Filter *f, BerValue *dn, AttributeDescription *memberof_ad)
static int autogroup_modify_entry (Operation *op, SlapReply *rs)
static int autogroup_modrdn_entry (Operation *op, SlapReply *rs)
static int autogroup_build_def_filter (autogroup_def_t *agd, Operation *op)
static int ag_cfgen (ConfigArgs *c)
static int autogroup_db_open (BackendDB *be, ConfigReply *cr)
static int autogroup_db_close (BackendDB *be, ConfigReply *cr)
static int autogroup_db_destroy (BackendDB *be, ConfigReply *cr)
static int autogroup_initialize (void)
int init_module (int argc, char *argv[])

Variables

static ConfigDriver ag_cfgen
static ConfigTable agcfg []
static ConfigOCs agocs []
int slapMode
static slap_overinst autogroup = { { NULL } }

Class Documentation

struct autogroup_filter_t

Definition at line 42 of file autogroup.c.

Collaboration diagram for autogroup_filter_t:
Class Members
AttributeName * agf_anlist
Filter * agf_filter
struct autogroup_filter_t * agf_next
int agf_scope
struct autogroup_def_t

Definition at line 53 of file autogroup.c.

Collaboration diagram for autogroup_def_t:
Class Members
AttributeDescription * agd_member_ad
AttributeDescription * agd_member_url_ad
struct autogroup_def_t * agd_next
ObjectClass * agd_oc
struct autogroup_entry_t

Definition at line 61 of file autogroup.c.

Collaboration diagram for autogroup_entry_t:
Class Members
autogroup_def_t * age_def
BerValue age_dn
autogroup_filter_t * age_filter
int age_modrdn_olddnmodified
int age_mustrefresh
ldap_pvt_thread_mutex_t age_mutex
BerValue age_ndn
struct autogroup_entry_t * age_next
struct autogroup_info_t

Definition at line 73 of file autogroup.c.

Collaboration diagram for autogroup_info_t:
Class Members
autogroup_def_t * agi_def
autogroup_entry_t * agi_entry
AttributeDescription * agi_memberof_ad
ldap_pvt_thread_mutex_t agi_mutex
struct autogroup_sc_t

Definition at line 81 of file autogroup.c.

Collaboration diagram for autogroup_sc_t:
Class Members
autogroup_def_t * ags_def
autogroup_info_t * ags_info
struct autogroup_ga_t

Definition at line 87 of file autogroup.c.

Collaboration diagram for autogroup_ga_t:
Class Members
Entry * agg_entry
autogroup_filter_t * agg_filter
autogroup_entry_t * agg_group
Modifications * agg_mod
Modifications * agg_mod_last

Define Documentation

#define SLAPD_MEMBEROF_ATTR   "memberOf"

Definition at line 38 of file autogroup.c.


Typedef Documentation


Enumeration Type Documentation

anonymous enum
Enumerator:
AG_ATTRSET 
AG_MEMBER_OF_AD 
AG_LAST 

Definition at line 1521 of file autogroup.c.


Function Documentation

static int ag_cfgen ( ConfigArgs c) [static]

Definition at line 1565 of file autogroup.c.

{
       slap_overinst        *on = (slap_overinst *)c->bi;
       autogroup_info_t            *agi = (autogroup_info_t *)on->on_bi.bi_private;
       autogroup_def_t             *agd;
       autogroup_entry_t    *age;

       int rc = 0, i;

       Debug( LDAP_DEBUG_TRACE, "==> autogroup_cfgen\n", 0, 0, 0);

       if( agi == NULL ) {
              agi = (autogroup_info_t*)ch_calloc( 1, sizeof(autogroup_info_t) );
              ldap_pvt_thread_mutex_init( &agi->agi_mutex );
              agi->agi_def = NULL;
              agi->agi_entry = NULL;
              on->on_bi.bi_private = (void *)agi;
       }

       agd = agi->agi_def;
       age = agi->agi_entry;

       if ( c->op == SLAP_CONFIG_EMIT ) {

              switch( c->type ){
              case AG_ATTRSET:
                     for ( i = 0 ; agd ; i++, agd = agd->agd_next ) {
                            struct berval bv;
                            char          *ptr = c->cr_msg;
       
                            assert(agd->agd_oc != NULL);
                            assert(agd->agd_member_url_ad != NULL);
                            assert(agd->agd_member_ad != NULL);
       
                            ptr += snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                   SLAP_X_ORDERED_FMT "%s %s %s", i,
                                   agd->agd_oc->soc_cname.bv_val,
                                   agd->agd_member_url_ad->ad_cname.bv_val,
                                   agd->agd_member_ad->ad_cname.bv_val );
       
                            bv.bv_val = c->cr_msg;
                            bv.bv_len = ptr - bv.bv_val;
                            value_add_one ( &c->rvalue_vals, &bv );
       
                     }
                     break;

              case AG_MEMBER_OF_AD:
                     if ( agi->agi_memberof_ad != NULL ){
                            value_add_one( &c->rvalue_vals, &agi->agi_memberof_ad->ad_cname );
                     }
                     break;

              default:
                     assert( 0 );
                     return 1;
      }

              return rc;

       }else if ( c->op == LDAP_MOD_DELETE ) {
              if ( c->valx < 0) {
                     autogroup_def_t             *agd_next;
                     autogroup_entry_t    *age_next;
                     autogroup_filter_t   *agf = age->age_filter,
                                          *agf_next;

                     for ( agd_next = agd; agd_next; agd = agd_next ) {
                            agd_next = agd->agd_next;

                            ch_free( agd );
                     }

                     for ( age_next = age ; age_next ; age = age_next ) {
                            age_next = age->age_next;

                            ch_free( age->age_dn.bv_val );
                            ch_free( age->age_ndn.bv_val );

                            for( agf_next = agf ; agf_next ; agf = agf_next ){
                                   agf_next = agf->agf_next;

                                   filter_free( agf->agf_filter );
                                   ch_free( agf->agf_filterstr.bv_val );
                                   ch_free( agf->agf_dn.bv_val );
                                   ch_free( agf->agf_ndn.bv_val );
                                   anlist_free( agf->agf_anlist, 1, NULL );
                                   ch_free( agf );
                            }

                            ldap_pvt_thread_mutex_init( &age->age_mutex );
                            ch_free( age );
                     }

                     ch_free( agi );
                     on->on_bi.bi_private = NULL;

              } else {
                     autogroup_def_t             **agdp;
                     autogroup_entry_t    *age_next, *age_prev;
                     autogroup_filter_t   *agf,
                                          *agf_next;

                     for ( i = 0, agdp = &agi->agi_def;
                            i < c->valx; i++ ) 
                     {
                            if ( *agdp == NULL) {
                                   return 1;
                            }
                            agdp = &(*agdp)->agd_next;
                     }

                     agd = *agdp;
                     *agdp = agd->agd_next;

                     for ( age_next = age , age_prev = NULL ; age_next ; age_prev = age, age = age_next ) {
                            age_next = age->age_next;

                            if( age->age_def == agd ) {
                                   agf = age->age_filter;

                                   ch_free( age->age_dn.bv_val );
                                   ch_free( age->age_ndn.bv_val );

                                   for ( agf_next = agf; agf_next ; agf = agf_next ) {
                                          agf_next = agf->agf_next;
                                          filter_free( agf->agf_filter );
                                          ch_free( agf->agf_filterstr.bv_val );
                                          ch_free( agf->agf_dn.bv_val );
                                          ch_free( agf->agf_ndn.bv_val );
                                          anlist_free( agf->agf_anlist, 1, NULL );
                                          ch_free( agf );
                                   }

                                   ldap_pvt_thread_mutex_destroy( &age->age_mutex );
                                   ch_free( age );

                                   age = age_prev;

                                   if( age_prev != NULL ) {
                                          age_prev->age_next = age_next;
                                   }
                            }
                     }

                     ch_free( agd );
                     agd = agi->agi_def;

              }

              return rc;
       }

       switch(c->type){
       case AG_ATTRSET: {
              autogroup_def_t             **agdp,
                                   *agd_next = NULL;
              ObjectClass          *oc = NULL;
              AttributeDescription *member_url_ad = NULL,
                                   *member_ad = NULL;
              const char           *text;


              oc = oc_find( c->argv[ 1 ] );
              if( oc == NULL ){
                     snprintf( c->cr_msg, sizeof( c->cr_msg ),
                            "\"autogroup-attrset <oc> <URL-ad> <member-ad>\": "
                            "unable to find ObjectClass \"%s\"",
                            c->argv[ 1 ] );
                     Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
                            c->log, c->cr_msg, 0 );
                     return 1;
              }


              rc = slap_str2ad( c->argv[ 2 ], &member_url_ad, &text );
              if( rc != LDAP_SUCCESS ) {
                     snprintf( c->cr_msg, sizeof( c->cr_msg ),
                            "\"autogroup-attrset <oc> <URL-ad> <member-ad>\": "
                            "unable to find AttributeDescription \"%s\"",
                            c->argv[ 2 ] );
                     Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
                            c->log, c->cr_msg, 0 );            
                     return 1;
              }

              if( !is_at_subtype( member_url_ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) {
                     snprintf( c->cr_msg, sizeof( c->cr_msg ),
                            "\"autogroup-attrset <oc> <URL-ad> <member-ad>\": "
                            "AttributeDescription \"%s\" ",
                            "must be of a subtype \"labeledURI\"",
                            c->argv[ 2 ] );
                     Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
                            c->log, c->cr_msg, 0 );
                     return 1;
              }

              rc = slap_str2ad( c->argv[3], &member_ad, &text );
              if( rc != LDAP_SUCCESS ) {
                     snprintf( c->cr_msg, sizeof( c->cr_msg ),
                            "\"autogroup-attrset <oc> <URL-ad> <member-ad>\": "
                            "unable to find AttributeDescription \"%s\"",
                            c->argv[ 3 ] );
                     Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
                            c->log, c->cr_msg, 0 );
                     return 1;
              }

              for ( agdp = &agi->agi_def ; *agdp ; agdp = &(*agdp)->agd_next ) {
                     /* The same URL attribute / member attribute pair
                     * cannot be repeated */

                     if ( (*agdp)->agd_member_url_ad == member_url_ad && (*agdp)->agd_member_ad == member_ad ) {
                            snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                   "\"autogroup-attrset <oc> <URL-ad> <member-ad>\": "
                                   "URL attributeDescription \"%s\" already mapped",
                                   member_ad->ad_cname.bv_val );
                            Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
                                   c->log, c->cr_msg, 0 );
/*                          return 1; //warning*/
                     }
              }

              if ( c->valx > 0 ) {
                     int    i;

                     for ( i = 0, agdp = &agi->agi_def ;
                            i < c->valx; i++ )
                     {
                            if ( *agdp == NULL ) {
                                   snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                          "\"autogroup-attrset <oc> <URL-ad> <member-ad>\": "
                                          "invalid index {%d}",
                                          c->valx );
                                   Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
                                          c->log, c->cr_msg, 0 );

                                   return 1;
                            }
                            agdp = &(*agdp)->agd_next;
                     }
                     agd_next = *agdp;

              } else {
                     for ( agdp = &agi->agi_def; *agdp;
                            agdp = &(*agdp)->agd_next )
                            /* goto last */;
              }

              *agdp = (autogroup_def_t *)ch_calloc( 1, sizeof(autogroup_info_t));

              (*agdp)->agd_oc = oc;
              (*agdp)->agd_member_url_ad = member_url_ad;
              (*agdp)->agd_member_ad = member_ad;
              (*agdp)->agd_next = agd_next;

              } break;
       
       case AG_MEMBER_OF_AD: {
              AttributeDescription *memberof_ad = NULL;
              const char     *text;

              rc = slap_str2ad( c->argv[ 1 ], &memberof_ad, &text );
              if( rc != LDAP_SUCCESS ) {
                     snprintf( c->cr_msg, sizeof( c->cr_msg ),
                            "\"autogroup-memberof-ad <memberof-ad>\": "
                            "unable to find AttributeDescription \"%s\"",
                            c->argv[ 1 ] );
                     Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
                            c->log, c->cr_msg, 0 );
                     return 1;
              }

              if ( !is_at_syntax( memberof_ad->ad_type, SLAPD_DN_SYNTAX )    /* e.g. "member" */
                   && !is_at_syntax( memberof_ad->ad_type, SLAPD_NAMEUID_SYNTAX ) )  /* e.g. "uniqueMember" */
              {
                     snprintf( c->cr_msg, sizeof( c->cr_msg ),
                            "memberof attribute=\"%s\" must either "
                            "have DN (%s) or nameUID (%s) syntax",
                            c->argv[ 1 ], SLAPD_DN_SYNTAX, SLAPD_NAMEUID_SYNTAX );
                     Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
                            c->log, c->cr_msg, 0 );
                     return 1;
              }

              agi->agi_memberof_ad = memberof_ad;

              } break;

       default:
              rc = 1;
              break;
       }

       return rc;
}

Here is the call graph for this function:

static int autogroup_add_entry ( Operation op,
SlapReply rs 
) [static]

Definition at line 718 of file autogroup.c.

{
       slap_overinst        *on = (slap_overinst *)op->o_bd->bd_info;
       autogroup_info_t     *agi = (autogroup_info_t *)on->on_bi.bi_private;
       autogroup_def_t             *agd = agi->agi_def;
       autogroup_entry_t    *age;
       autogroup_filter_t   *agf;
       int                  rc = 0;

       Debug( LDAP_DEBUG_TRACE, "==> autogroup_add_entry <%s>\n", 
              op->ora_e->e_name.bv_val, 0, 0);

       ldap_pvt_thread_mutex_lock( &agi->agi_mutex );          

       /* Check if it's a group. */
       for ( ; agd ; agd = agd->agd_next ) {
              if ( is_entry_objectclass_or_sub( op->ora_e, agd->agd_oc ) ) {
                     Modification         mod;
                     const char           *text = NULL;
                     char                 textbuf[1024];

                     mod.sm_op = LDAP_MOD_DELETE;
                     mod.sm_desc = agd->agd_member_ad;
                     mod.sm_type = agd->agd_member_ad->ad_cname;
                     mod.sm_values = NULL;
                     mod.sm_nvalues = NULL;

                     /* We don't want any member attributes added by the user. */
                     modify_delete_values( op->ora_e, &mod, /* permissive */ 1, &text, textbuf, sizeof( textbuf ) );

                     autogroup_add_group( op, agi, agd, op->ora_e, NULL, 1 , 0);
                     ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );        
                     return SLAP_CB_CONTINUE;
              }
       }

       
       for ( age = agi->agi_entry; age ; age = age->age_next ) {
              ldap_pvt_thread_mutex_lock( &age->age_mutex );          

              /* Check if any of the filters are the suffix to the entry DN. 
                 If yes, we can test that filter against the entry. */

              for ( agf = age->age_filter; agf ; agf = agf->agf_next ) {
                     if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
                            rc = test_filter( op, op->ora_e, agf->agf_filter );
                            if ( rc == LDAP_COMPARE_TRUE ) {
                                   if ( agf->agf_anlist ) {
                                          autogroup_add_member_values_to_group( op, op->ora_e, age, agf->agf_anlist[0].an_desc );
                                   } else {
                                          autogroup_add_member_to_group( op, &op->ora_e->e_name, &op->ora_e->e_nname, age );
                                   }
                                   break;
                            }
                     }
              }
              ldap_pvt_thread_mutex_unlock( &age->age_mutex );        
       }

       ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );        

       return SLAP_CB_CONTINUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int autogroup_add_group ( Operation op,
autogroup_info_t agi,
autogroup_def_t agd,
Entry e,
BerValue ndn,
int  scan,
int  modify 
) [static]

Definition at line 539 of file autogroup.c.

{
       autogroup_entry_t    **agep = &agi->agi_entry;
       autogroup_filter_t   *agf, *agf_prev = NULL;
       slap_overinst        *on = (slap_overinst *)op->o_bd->bd_info;
       LDAPURLDesc          *lud = NULL;
       Attribute            *a;
       BerValue             *bv, dn;
       int                  rc = 0, match = 1, null_entry = 0;

       if ( e == NULL ) {
              if ( overlay_entry_get_ov( op, ndn, NULL, NULL, 0, &e, on ) !=
                     LDAP_SUCCESS || e == NULL ) {
                     Debug( LDAP_DEBUG_TRACE, "autogroup_add_group: cannot get entry for <%s>\n", ndn->bv_val, 0, 0);
                     return 1;
              }

              null_entry = 1;
       }

       Debug(LDAP_DEBUG_TRACE, "==> autogroup_add_group <%s>\n",
              e->e_name.bv_val, 0, 0);

       if ( agi->agi_entry != NULL ) {
              for ( ; *agep ; agep = &(*agep)->age_next ) {
                     dnMatch( &match, 0, NULL, NULL, &e->e_nname, &(*agep)->age_ndn );
                     if ( match == 0 ) {
                            Debug( LDAP_DEBUG_TRACE, "autogroup_add_group: group already exists: <%s>\n", e->e_name.bv_val,0,0);
                            return 1;
                     }
                     /* goto last */;
              }
       }


       *agep = (autogroup_entry_t *)ch_calloc( 1, sizeof( autogroup_entry_t ) );
       ldap_pvt_thread_mutex_init( &(*agep)->age_mutex );
       (*agep)->age_def = agd;
       (*agep)->age_filter = NULL;
       (*agep)->age_mustrefresh = 0;
       (*agep)->age_modrdn_olddnmodified = 0;

       ber_dupbv( &(*agep)->age_dn, &e->e_name );
       ber_dupbv( &(*agep)->age_ndn, &e->e_nname );

       a = attrs_find( e->e_attrs, agd->agd_member_url_ad );

       if ( null_entry == 1 ) {
              a = attrs_dup( a );
              overlay_entry_release_ov( op, e, 0, on );
       }

       if( a == NULL ) {
              Debug( LDAP_DEBUG_TRACE, "autogroup_add_group: group has no memberURL\n", 0,0,0);
       } else {
              for ( bv = a->a_nvals; !BER_BVISNULL( bv ); bv++ ) {

                     agf = (autogroup_filter_t*)ch_calloc( 1, sizeof( autogroup_filter_t ) );

                     if ( ldap_url_parse( bv->bv_val, &lud ) != LDAP_URL_SUCCESS ) {
                            Debug( LDAP_DEBUG_TRACE, "autogroup_add_group: cannot parse url <%s>\n", bv->bv_val,0,0);
                            /* FIXME: error? */
                            ch_free( agf ); 
                            continue;
                     }

                     agf->agf_scope = lud->lud_scope;

                     if ( lud->lud_dn == NULL ) {
                            BER_BVSTR( &dn, "" );
                     } else {
                            ber_str2bv( lud->lud_dn, 0, 0, &dn );
                     }

                     rc = dnPrettyNormal( NULL, &dn, &agf->agf_dn, &agf->agf_ndn, NULL );
                     if ( rc != LDAP_SUCCESS ) {
                            Debug( LDAP_DEBUG_TRACE, "autogroup_add_group: cannot normalize DN <%s>\n", dn.bv_val,0,0);
                            /* FIXME: error? */
                            goto cleanup;
                     }

                     if ( lud->lud_filter != NULL ) {
                            ber_str2bv( lud->lud_filter, 0, 1, &agf->agf_filterstr);
                            agf->agf_filter = str2filter( lud->lud_filter );
                     }                    

                     if ( lud->lud_attrs != NULL ) {
                            int i;

                            for ( i=0 ; lud->lud_attrs[i]!=NULL ; i++) {
                                   /* Just counting */;
                            }

                            if ( i > 1 ) {
                                   Debug( LDAP_DEBUG_ANY, "autogroup_add_group: too many attributes specified in url <%s>\n",
                                          bv->bv_val, 0, 0);
                                   /* FIXME: error? */
                                   ldap_free_urldesc( lud );
                                   ch_free( agf ); 
                                   continue;
                            }
                                   
                            agf->agf_anlist = str2anlist( NULL, lud->lud_attrs[0], "," );

                            if ( agf->agf_anlist == NULL ) {
                                   Debug( LDAP_DEBUG_ANY, "autogroup_add_group: unable to find AttributeDescription \"%s\".\n",
                                          lud->lud_attrs[0], 0, 0 );         
                                   /* FIXME: error? */
                                   ldap_free_urldesc( lud );
                                   ch_free( agf ); 
                                   continue;
                            }
                     }

                     agf->agf_next = NULL;


                     if( (*agep)->age_filter == NULL ) {
                            (*agep)->age_filter = agf;
                     }

                     if( agf_prev != NULL ) {
                            agf_prev->agf_next = agf;
                     }

                     agf_prev = agf;

                     if ( scan == 1 ){
                            autogroup_add_members_from_filter( op, e, (*agep), agf, modify );
                     }

                     Debug( LDAP_DEBUG_TRACE, "autogroup_add_group: added memberURL DN <%s> with filter <%s>\n",
                            agf->agf_ndn.bv_val, agf->agf_filterstr.bv_val, 0);

                     ldap_free_urldesc( lud );

                     continue;


cleanup:;

                     ldap_free_urldesc( lud );                        
                     ch_free( agf ); 
              }
       }

       if ( null_entry == 1 ) {
              attrs_free( a );
       }
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int autogroup_add_member_to_group ( Operation op,
BerValue dn,
BerValue ndn,
autogroup_entry_t age 
) [static]

Definition at line 106 of file autogroup.c.

{
       slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
       Modifications *modlist = (Modifications *)ch_calloc( 1, sizeof( Modifications ) );
       SlapReply     sreply = {REP_RESULT};
       BerValue      *vals, *nvals;
       slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
       Operation     o = *op;

       assert( dn != NULL );
       assert( ndn != NULL );
       Debug(LDAP_DEBUG_TRACE, "==> autogroup_add_member_to_group adding <%s> to <%s>\n",
              dn->bv_val, age->age_dn.bv_val, 0);

       vals = (BerValue *)ch_calloc( 2, sizeof( BerValue ) );
       nvals = (BerValue *)ch_calloc( 2, sizeof( BerValue ) );
       ber_dupbv( vals, dn );
       BER_BVZERO( &vals[ 1 ] );
       ber_dupbv( nvals, ndn );
       BER_BVZERO( &nvals[ 1 ] );

       modlist->sml_op = LDAP_MOD_ADD;
       modlist->sml_desc = age->age_def->agd_member_ad;
       modlist->sml_type = age->age_def->agd_member_ad->ad_cname;
       modlist->sml_values = vals;
       modlist->sml_nvalues = nvals;
       modlist->sml_numvals = 1;
       modlist->sml_flags = SLAP_MOD_INTERNAL;
       modlist->sml_next = NULL;

       o.o_tag = LDAP_REQ_MODIFY;
       o.o_callback = &cb;
       o.orm_modlist = modlist;
       o.o_req_dn = age->age_dn;
       o.o_req_ndn = age->age_ndn;
       o.o_permissive_modify = 1;
       o.o_managedsait = SLAP_CONTROL_CRITICAL;
       o.o_relax = SLAP_CONTROL_CRITICAL;

       o.o_bd->bd_info = (BackendInfo *)on->on_info;
       (void)op->o_bd->be_modify( &o, &sreply );
       o.o_bd->bd_info = (BackendInfo *)on;

       slap_mods_free( modlist, 1 );

       return sreply.sr_err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int autogroup_add_member_values_to_group ( Operation op,
Entry e,
autogroup_entry_t age,
AttributeDescription attrdesc 
) [static]

Definition at line 159 of file autogroup.c.

{
       slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
       Modifications modlist;
       SlapReply     sreply = {REP_RESULT};
       Attribute     *attr;
       slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
       Operation     o = *op;

       assert( e != NULL );
       Debug(LDAP_DEBUG_TRACE, "==> autogroup_add_member_values_to_group adding <%s> to <%s>\n",
              e->e_name.bv_val, age->age_dn.bv_val, 0);

       attr = attrs_find( e->e_attrs, attrdesc );
       if (!attr) {
              // Nothing to add
              return LDAP_SUCCESS;
       }

       modlist.sml_op = LDAP_MOD_ADD;
       modlist.sml_desc = age->age_def->agd_member_ad;
       modlist.sml_type = age->age_def->agd_member_ad->ad_cname;
       modlist.sml_values = attr->a_vals;
       modlist.sml_nvalues = attr->a_nvals;
       modlist.sml_numvals = attr->a_numvals;
       modlist.sml_flags = SLAP_MOD_INTERNAL;
       modlist.sml_next = NULL;

       o.o_tag = LDAP_REQ_MODIFY;
       o.o_callback = &cb;
       o.orm_modlist = &modlist;
       o.o_req_dn = age->age_dn;
       o.o_req_ndn = age->age_ndn;
       o.o_permissive_modify = 1;
       o.o_managedsait = SLAP_CONTROL_CRITICAL;
       o.o_relax = SLAP_CONTROL_CRITICAL;

       o.o_bd->bd_info = (BackendInfo *)on->on_info;
       (void)op->o_bd->be_modify( &o, &sreply );
       o.o_bd->bd_info = (BackendInfo *)on;

       return sreply.sr_err;
}

Here is the caller graph for this function:

static int autogroup_add_members_from_filter ( Operation op,
Entry e,
autogroup_entry_t age,
autogroup_filter_t agf,
int  modify 
) [static]

Definition at line 455 of file autogroup.c.

{
       slap_overinst        *on = (slap_overinst *)op->o_bd->bd_info;
       Operation            o = *op;
       SlapReply            rs = { REP_SEARCH };
       slap_callback        cb = { 0 };
       slap_callback        null_cb = { NULL, slap_null_cb, NULL, NULL };
       autogroup_ga_t              agg;

       Debug(LDAP_DEBUG_TRACE, "==> autogroup_add_members_from_filter <%s>\n",
              age->age_dn.bv_val, 0, 0);

       o.ors_attrsonly = 0;
       o.o_tag = LDAP_REQ_SEARCH;

       o.o_req_dn = agf->agf_dn;
       o.o_req_ndn = agf->agf_ndn;

       o.ors_filterstr = agf->agf_filterstr;
       o.ors_filter = agf->agf_filter;

       o.ors_scope = agf->agf_scope;
       o.ors_deref = LDAP_DEREF_NEVER;
       o.ors_limit = NULL;
       o.ors_tlimit = SLAP_NO_LIMIT;
       o.ors_slimit = SLAP_NO_LIMIT;
       o.ors_attrs =  agf->agf_anlist ? agf->agf_anlist : slap_anlist_no_attrs;

       agg.agg_group = age;
       agg.agg_filter = agf;
       agg.agg_mod = NULL;
       agg.agg_mod_last = NULL;
       agg.agg_entry = e;
       cb.sc_private = &agg;

       if ( modify == 1 ) {
              cb.sc_response = autogroup_member_search_modify_cb;
       } else {
              cb.sc_response = autogroup_member_search_cb;
       }

       cb.sc_cleanup = NULL;
       cb.sc_next = NULL;

       o.o_callback = &cb;

       o.o_bd->bd_info = (BackendInfo *)on->on_info;
       op->o_bd->be_search( &o, &rs );
       o.o_bd->bd_info = (BackendInfo *)on;      

       if ( modify == 1 && agg.agg_mod ) {
              rs_reinit( &rs, REP_RESULT );

              o = *op;
              o.o_callback = &null_cb;
              o.o_tag = LDAP_REQ_MODIFY;
              o.orm_modlist = agg.agg_mod;
              o.o_req_dn = age->age_dn;
              o.o_req_ndn = age->age_ndn;
              o.o_relax = SLAP_CONTROL_CRITICAL;
              o.o_managedsait = SLAP_CONTROL_NONCRITICAL;
              o.o_permissive_modify = 1;

              o.o_bd->bd_info = (BackendInfo *)on->on_info;
              (void)op->o_bd->be_modify( &o, &rs );
              o.o_bd->bd_info = (BackendInfo *)on;      

              slap_mods_free(agg.agg_mod, 1);
       }

       return 0;
}

Here is the caller graph for this function:

static int autogroup_build_def_filter ( autogroup_def_t agd,
Operation op 
) [static]

Definition at line 1497 of file autogroup.c.

{
       char   *ptr;

       Debug( LDAP_DEBUG_TRACE, "==> autogroup_build_def_filter\n", 0, 0, 0);

       op->ors_filterstr.bv_len = STRLENOF( "(=)" ) 
                     + slap_schema.si_ad_objectClass->ad_cname.bv_len
                     + agd->agd_oc->soc_cname.bv_len;
       ptr = op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx );
       *ptr++ = '(';
       ptr = lutil_strcopy( ptr, slap_schema.si_ad_objectClass->ad_cname.bv_val );
       *ptr++ = '=';
       ptr = lutil_strcopy( ptr, agd->agd_oc->soc_cname.bv_val );
       *ptr++ = ')';
       *ptr = '\0';

       op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val );

       assert( op->ors_filterstr.bv_len == ptr - op->ors_filterstr.bv_val );

       return 0;
}

Here is the call graph for this function:

static int autogroup_db_close ( BackendDB be,
ConfigReply *  cr 
) [static]

Definition at line 1949 of file autogroup.c.

{
       slap_overinst               *on = (slap_overinst *) be->bd_info;

       Debug( LDAP_DEBUG_TRACE, "==> autogroup_db_close\n", 0, 0, 0);

       if ( on->on_bi.bi_private ) {
              autogroup_info_t            *agi = on->on_bi.bi_private;
              autogroup_entry_t    *age = agi->agi_entry,
                                   *age_next;
              autogroup_filter_t   *agf, *agf_next;

              for ( age_next = age; age_next; age = age_next ) {
                     age_next = age->age_next;

                     ch_free( age->age_dn.bv_val );
                     ch_free( age->age_ndn.bv_val );

                     agf = age->age_filter;

                     for ( agf_next = agf; agf_next; agf = agf_next ) {
                            agf_next = agf->agf_next;

                            filter_free( agf->agf_filter );
                            ch_free( agf->agf_filterstr.bv_val );
                            ch_free( agf->agf_dn.bv_val );
                            ch_free( agf->agf_ndn.bv_val );    
                            anlist_free( agf->agf_anlist, 1, NULL );
                            ch_free( agf );
                     }

                     ldap_pvt_thread_mutex_destroy( &age->age_mutex );
                     ch_free( age );
              }
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int autogroup_db_destroy ( BackendDB be,
ConfigReply *  cr 
) [static]

Definition at line 1991 of file autogroup.c.

{
       slap_overinst               *on = (slap_overinst *) be->bd_info;

       Debug( LDAP_DEBUG_TRACE, "==> autogroup_db_destroy\n", 0, 0, 0);

       if ( on->on_bi.bi_private ) {
              autogroup_info_t            *agi = on->on_bi.bi_private;
              autogroup_def_t             *agd = agi->agi_def,
                                   *agd_next;

              for ( agd_next = agd; agd_next; agd = agd_next ) {
                     agd_next = agd->agd_next;

                     ch_free( agd );
              }

              ldap_pvt_thread_mutex_destroy( &agi->agi_mutex );
              ch_free( agi );
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int autogroup_db_open ( BackendDB be,
ConfigReply *  cr 
) [static]

Definition at line 1869 of file autogroup.c.

{
       slap_overinst               *on = (slap_overinst *) be->bd_info;
       autogroup_info_t            *agi = on->on_bi.bi_private;
       autogroup_def_t             *agd;
       autogroup_sc_t              ags;
       Operation            *op;
       slap_callback        cb = { 0 };

       void                        *thrctx = ldap_pvt_thread_pool_context();
       Connection                  conn = { 0 };
       OperationBuffer      opbuf;

       Debug( LDAP_DEBUG_TRACE, "==> autogroup_db_open\n", 0, 0, 0);

       if ( agi == NULL || !( slapMode & SLAP_SERVER_MODE )) {
              return 0;
       }

       connection_fake_init( &conn, &opbuf, thrctx );
       op = &opbuf.ob_op;

       op->ors_attrsonly = 0;
       op->o_tag = LDAP_REQ_SEARCH;
       op->o_dn = be->be_rootdn;
       op->o_ndn = be->be_rootndn;

       op->o_req_dn = be->be_suffix[0];
       op->o_req_ndn = be->be_nsuffix[0];

       op->ors_scope = LDAP_SCOPE_SUBTREE;
       op->ors_deref = LDAP_DEREF_NEVER;
       op->ors_limit = NULL;
       op->ors_tlimit = SLAP_NO_LIMIT;
       op->ors_slimit = SLAP_NO_LIMIT;
       op->ors_attrs =  slap_anlist_no_attrs;

       op->o_bd = be;
       op->o_bd->bd_info = (BackendInfo *)on->on_info;

       ags.ags_info = agi;
       cb.sc_private = &ags;
       cb.sc_response = autogroup_group_add_cb;
       cb.sc_cleanup = NULL;
       cb.sc_next = NULL;

       op->o_callback = &cb;

       for (agd = agi->agi_def ; agd ; agd = agd->agd_next) {
              SlapReply     rs = { REP_RESULT };

              autogroup_build_def_filter(agd, op);

              ags.ags_def = agd;

              op->o_bd->be_search( op, &rs );

              filter_free_x( op, op->ors_filter, 1 );
              op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
       }             

       if( ! agi->agi_memberof_ad ){
              int                  rc;
              const char           *text = NULL;
              
              rc = slap_str2ad( SLAPD_MEMBEROF_ATTR, &agi->agi_memberof_ad, &text );
              if ( rc != LDAP_SUCCESS ) {
                     Debug( LDAP_DEBUG_ANY, "autogroup_db_open: "
                     "unable to find attribute=\"%s\": %s (%d)\n",
                     SLAPD_MEMBEROF_ATTR, text, rc );
                     return rc;
              }
       }

       return 0;
}

Here is the caller graph for this function:

static int autogroup_delete_entry ( Operation op,
SlapReply rs 
) [static]

Definition at line 841 of file autogroup.c.

{
       slap_overinst        *on = (slap_overinst *)op->o_bd->bd_info;
       autogroup_info_t     *agi = (autogroup_info_t *)on->on_bi.bi_private;
       autogroup_entry_t    *age, *age_prev, *age_next;
       autogroup_filter_t   *agf;
       Entry                *e;
       int                  matched_group = 0, rc = 0;

       Debug( LDAP_DEBUG_TRACE, "==> autogroup_delete_entry <%s>\n", op->o_req_dn.bv_val, 0, 0);

       ldap_pvt_thread_mutex_lock( &agi->agi_mutex );

       if ( overlay_entry_get_ov( op, &op->o_req_ndn, NULL, NULL, 0, &e, on ) !=
              LDAP_SUCCESS || e == NULL ) {
              Debug( LDAP_DEBUG_TRACE, "autogroup_delete_entry: cannot get entry for <%s>\n", op->o_req_dn.bv_val, 0, 0);
              ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );               
              return SLAP_CB_CONTINUE;
       }

       /* Check if the entry to be deleted is one of our groups. */
       for ( age_next = agi->agi_entry ; age_next ; age_prev = age ) {
              age = age_next;
              ldap_pvt_thread_mutex_lock( &age->age_mutex );
              age_next = age->age_next;

              if ( is_entry_objectclass_or_sub( e, age->age_def->agd_oc ) ) {
                     int match = 1;

                     matched_group = 1;

                     dnMatch( &match, 0, NULL, NULL, &e->e_nname, &age->age_ndn );

                     if ( match == 0 ) {
                            autogroup_delete_group( agi, age );
                            break;
                     }
              }

              ldap_pvt_thread_mutex_unlock( &age->age_mutex );               
       }

       if ( matched_group == 1 ) {
              overlay_entry_release_ov( op, e, 0, on );
              ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );        
              return SLAP_CB_CONTINUE;
       }

       /* Check if the entry matches any of the groups.
          If yes, we can delete the entry from that group. */

       for ( age = agi->agi_entry ; age ; age = age->age_next ) {
              ldap_pvt_thread_mutex_lock( &age->age_mutex );          

              for ( agf = age->age_filter; agf ; agf = agf->agf_next ) {
                     if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
                            rc = test_filter( op, e, agf->agf_filter );
                            if ( rc == LDAP_COMPARE_TRUE ) {
                                   /* If the attribute is retrieved from the entry, we don't know what to delete
                                   ** So the group must be entirely refreshed
                                   ** But the refresh can't be done now because the entry is not deleted
                                   ** So the group is marked as mustrefresh
                                   */
                                   if ( agf->agf_anlist ) {
                                          age->age_mustrefresh = 1;
                                   } else {
                                          autogroup_delete_member_from_group( op, &e->e_name, &e->e_nname, age );
                                   }
                                   break;
                            }
                     }
              }
              ldap_pvt_thread_mutex_unlock( &age->age_mutex );
       }

       overlay_entry_release_ov( op, e, 0, on );
       ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );        

       return SLAP_CB_CONTINUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int autogroup_delete_group ( autogroup_info_t agi,
autogroup_entry_t e 
) [static]

Definition at line 787 of file autogroup.c.

{
       autogroup_entry_t    *age = agi->agi_entry,
                            *age_prev = NULL,
                            *age_next;
       int                  rc = 1;

       Debug( LDAP_DEBUG_TRACE, "==> autogroup_delete_group <%s>\n", 
              age->age_dn.bv_val, 0, 0);

       for ( age_next = age ; age_next ; age_prev = age, age = age_next ) {
              age_next = age->age_next;

              if ( age == e ) {
                     autogroup_filter_t   *agf = age->age_filter,
                                                 *agf_next;

                     if ( age_prev != NULL ) {
                            age_prev->age_next = age_next;
                     } else {
                            agi->agi_entry = NULL;
                     }

                     ch_free( age->age_dn.bv_val );
                     ch_free( age->age_ndn.bv_val );

                     for( agf_next = agf ; agf_next ; agf = agf_next ){
                            agf_next = agf->agf_next;

                            filter_free( agf->agf_filter );
                            ch_free( agf->agf_filterstr.bv_val );
                            ch_free( agf->agf_dn.bv_val );
                            ch_free( agf->agf_ndn.bv_val );
                            anlist_free( agf->agf_anlist, 1, NULL );
                            ch_free( agf );
                     }

                     ldap_pvt_thread_mutex_unlock( &age->age_mutex );        
                     ldap_pvt_thread_mutex_destroy( &age->age_mutex );
                     ch_free( age );

                     rc = 0;       
                     return rc;

              }
       }

       Debug( LDAP_DEBUG_TRACE, "autogroup_delete_group: group <%s> not found, should not happen\n", age->age_dn.bv_val, 0, 0);

       return rc;

}

Here is the call graph for this function:

Here is the caller graph for this function:

static int autogroup_delete_member_from_group ( Operation op,
BerValue dn,
BerValue ndn,
autogroup_entry_t age 
) [static]

Definition at line 209 of file autogroup.c.

{
       slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
       Modifications *modlist = (Modifications *)ch_calloc( 1, sizeof( Modifications ) );
       SlapReply     sreply = {REP_RESULT};
       BerValue      *vals, *nvals;
       slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
       Operation     o = *op;

       if ( dn == NULL || ndn == NULL ) {
              Debug(LDAP_DEBUG_TRACE, "==> autogroup_delete_member_from_group removing all members from <%s>\n",
                     age->age_dn.bv_val, 0 ,0);

              modlist->sml_values = NULL;
              modlist->sml_nvalues = NULL;
              modlist->sml_numvals = 0;
       } else {
              Debug(LDAP_DEBUG_TRACE, "==> autogroup_delete_member_from_group removing <%s> from <%s>\n",
                     dn->bv_val, age->age_dn.bv_val, 0);

              vals = (BerValue *)ch_calloc( 2, sizeof( BerValue ) );
              nvals = (BerValue *)ch_calloc( 2, sizeof( BerValue ) );
              ber_dupbv( vals, dn );
              BER_BVZERO( &vals[ 1 ] );
              ber_dupbv( nvals, ndn );
              BER_BVZERO( &nvals[ 1 ] );

              modlist->sml_values = vals;
              modlist->sml_nvalues = nvals;
              modlist->sml_numvals = 1;
       }


       modlist->sml_op = LDAP_MOD_DELETE;
       modlist->sml_desc = age->age_def->agd_member_ad;
       modlist->sml_type = age->age_def->agd_member_ad->ad_cname;
       modlist->sml_flags = SLAP_MOD_INTERNAL;
       modlist->sml_next = NULL;

       o.o_callback = &cb;
       o.o_tag = LDAP_REQ_MODIFY;
       o.orm_modlist = modlist;
       o.o_req_dn = age->age_dn;
       o.o_req_ndn = age->age_ndn;
       o.o_relax = SLAP_CONTROL_CRITICAL;
       o.o_managedsait = SLAP_CONTROL_CRITICAL;
       o.o_permissive_modify = 1;

       o.o_bd->bd_info = (BackendInfo *)on->on_info;
       (void)op->o_bd->be_modify( &o, &sreply );
       o.o_bd->bd_info = (BackendInfo *)on;

       slap_mods_free( modlist, 1 );

       return sreply.sr_err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int autogroup_delete_member_values_from_group ( Operation op,
Entry e,
autogroup_entry_t age,
AttributeDescription attrdesc 
) [static]

Definition at line 271 of file autogroup.c.

{
        slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
        Modifications   modlist;
        SlapReply       sreply = {REP_RESULT};
        Attribute       *attr;
        slap_callback   cb = { NULL, slap_null_cb, NULL, NULL };
        Operation       o = *op;

        assert( e != NULL );
        Debug(LDAP_DEBUG_TRACE, "==> autogroup_delete_member_values_from_group removing <%s> from <%s>\n",
                e->e_name.bv_val, age->age_dn.bv_val, 0);

        attr = attrs_find( e->e_attrs, attrdesc );
        if (!attr) {
                // Nothing to add
                return LDAP_SUCCESS;
        }

        modlist.sml_op = LDAP_MOD_DELETE;
        modlist.sml_desc = age->age_def->agd_member_ad;
        modlist.sml_type = age->age_def->agd_member_ad->ad_cname;
        modlist.sml_values = attr->a_vals;
        modlist.sml_nvalues = attr->a_nvals;
        modlist.sml_numvals = attr->a_numvals;
        modlist.sml_flags = SLAP_MOD_INTERNAL;
        modlist.sml_next = NULL;

        o.o_tag = LDAP_REQ_MODIFY;
        o.o_callback = &cb;
        o.orm_modlist = &modlist;
        o.o_req_dn = age->age_dn;
        o.o_req_ndn = age->age_ndn;
        o.o_permissive_modify = 1;
        o.o_managedsait = SLAP_CONTROL_CRITICAL;
        o.o_relax = SLAP_CONTROL_CRITICAL;

        o.o_bd->bd_info = (BackendInfo *)on->on_info;
        (void)op->o_bd->be_modify( &o, &sreply );
        o.o_bd->bd_info = (BackendInfo *)on;

        return sreply.sr_err;
}

Here is the caller graph for this function:

static int autogroup_group_add_cb ( Operation op,
SlapReply rs 
) [static]

Definition at line 696 of file autogroup.c.

{
       assert( op->o_tag == LDAP_REQ_SEARCH );

       if ( rs->sr_type == REP_SEARCH ) {
              autogroup_sc_t              *ags = (autogroup_sc_t *)op->o_callback->sc_private;

              Debug(LDAP_DEBUG_TRACE, "==> autogroup_group_add_cb <%s>\n",
                     rs->sr_entry ? rs->sr_entry->e_name.bv_val : "UNKNOWN_DN", 0, 0);

              autogroup_add_group( op, ags->ags_info, ags->ags_def, rs->sr_entry, NULL, 0, 0);
       }

       return 0;
}

Here is the call graph for this function:

static int autogroup_initialize ( void  ) [static]
static int autogroup_member_search_cb ( Operation op,
SlapReply rs 
) [static]

Definition at line 322 of file autogroup.c.

{
       assert( op->o_tag == LDAP_REQ_SEARCH );

       if ( rs->sr_type == REP_SEARCH ) {
              autogroup_ga_t              *agg = (autogroup_ga_t *)op->o_callback->sc_private;
              autogroup_entry_t    *age = agg->agg_group;
              autogroup_filter_t   *agf = agg->agg_filter;
              Modification         mod;
              const char           *text = NULL;
              char                 textbuf[1024];
              struct berval        *vals, *nvals;
              int                  numvals;

              Debug(LDAP_DEBUG_TRACE, "==> autogroup_member_search_cb <%s>\n",
                     rs->sr_entry ? rs->sr_entry->e_name.bv_val : "UNKNOWN_DN", 0, 0);

              if ( agf->agf_anlist ) {
                     Attribute *attr = attrs_find( rs->sr_entry->e_attrs, agf->agf_anlist[0].an_desc );
                     if (attr) {
                            vals = attr->a_vals;
                            nvals = attr->a_nvals;
                            numvals = attr->a_numvals;
                     } else {
                            // Nothing to add
                            return 0;
                     }
              } else {
                     struct berval        lvals[ 2 ], lnvals[ 2 ];
                     lvals[ 0 ] = rs->sr_entry->e_name;
                     BER_BVZERO( &lvals[ 1 ] );
                     lnvals[ 0 ] = rs->sr_entry->e_nname;
                     BER_BVZERO( &lnvals[ 1 ] );
                     vals = lvals;
                     nvals = lnvals;
                     numvals = 1;
              }

              mod.sm_op = LDAP_MOD_ADD;
              mod.sm_desc = age->age_def->agd_member_ad;
              mod.sm_type = age->age_def->agd_member_ad->ad_cname;
              mod.sm_values = vals;
              mod.sm_nvalues = nvals;
              mod.sm_numvals = numvals;

              modify_add_values( agg->agg_entry, &mod, /* permissive */ 1, &text, textbuf, sizeof( textbuf ) );
       }

       return 0;
}

Here is the call graph for this function:

static int autogroup_member_search_modify_cb ( Operation op,
SlapReply rs 
) [static]

Definition at line 380 of file autogroup.c.

{
       assert( op->o_tag == LDAP_REQ_SEARCH );

       if ( rs->sr_type == REP_SEARCH ) {
              autogroup_ga_t              *agg = (autogroup_ga_t *)op->o_callback->sc_private;
              autogroup_entry_t    *age = agg->agg_group;
              autogroup_filter_t   *agf = agg->agg_filter;
              Modifications        *modlist;
              struct berval        *vals, *nvals;
              int                  numvals;

              Debug(LDAP_DEBUG_TRACE, "==> autogroup_member_search_modify_cb <%s>\n",
                     rs->sr_entry ? rs->sr_entry->e_name.bv_val : "UNKNOWN_DN", 0, 0);

              if ( agf->agf_anlist ) {
                     Attribute *attr = attrs_find( rs->sr_entry->e_attrs, agf->agf_anlist[0].an_desc );
                     if (attr) {
                            vals = attr->a_vals;
                            nvals = attr->a_nvals;
                            numvals = attr->a_numvals;
                     } else {
                            // Nothing to add
                            return 0;
                     }
              } else {
                     struct berval        lvals[ 2 ], lnvals[ 2 ];
                     lvals[ 0 ] = rs->sr_entry->e_name;
                     BER_BVZERO( &lvals[ 1 ] );
                     lnvals[ 0 ] = rs->sr_entry->e_nname;
                     BER_BVZERO( &lnvals[ 1 ] );
                     vals = lvals;
                     nvals = lnvals;
                     numvals = 1;
              }

              if ( numvals ) {
                     modlist = (Modifications *)ch_calloc( 1, sizeof( Modifications ) );

                     modlist->sml_op = LDAP_MOD_ADD;
                     modlist->sml_desc = age->age_def->agd_member_ad;
                     modlist->sml_type = age->age_def->agd_member_ad->ad_cname;

                     ber_bvarray_dup_x( &modlist->sml_values, vals, NULL );
                     ber_bvarray_dup_x( &modlist->sml_nvalues, nvals, NULL );
                     modlist->sml_numvals = numvals;

                     modlist->sml_flags = SLAP_MOD_INTERNAL;
                     modlist->sml_next = NULL;

                     if ( agg->agg_mod == NULL ) {
                            agg->agg_mod = modlist;
                            agg->agg_mod_last = modlist;
                     } else {
                            agg->agg_mod_last->sml_next = modlist;
                            agg->agg_mod_last = modlist;
                     }
              }

       }

       return 0;
}

Here is the call graph for this function:

static int autogroup_memberOf_filter ( Filter f,
BerValue dn,
AttributeDescription memberof_ad 
) [static]

Definition at line 1321 of file autogroup.c.

{
       int result = 0;
       if ( f == NULL ) return 0;

       switch ( f->f_choice & SLAPD_FILTER_MASK ) {
              case LDAP_FILTER_AND:
              case LDAP_FILTER_OR:
              case LDAP_FILTER_NOT:
                     for ( f = f->f_un.f_un_complex; f && !result; f = f->f_next ) {
                            result = result || autogroup_memberOf_filter( f, dn, memberof_ad );
                     }
                     break;
              case LDAP_FILTER_EQUALITY:
                     result = ( f->f_ava->aa_desc == memberof_ad &&
                                ber_bvcmp( &f->f_ava->aa_value, dn ) == 0 );
                     break;
              default:
                     break;
       }

       return result;
}

Here is the caller graph for this function:

static int autogroup_modify_entry ( Operation op,
SlapReply rs 
) [static]

Definition at line 1350 of file autogroup.c.

{
       slap_overinst        *on = (slap_overinst *)op->o_bd->bd_info;
       autogroup_info_t            *agi = (autogroup_info_t *)on->on_bi.bi_private;
       autogroup_def_t             *agd = agi->agi_def;
       autogroup_entry_t    *age;
       Entry                *e;
       Attribute            *a;

       if ( get_manageDSAit( op ) ) {
              return SLAP_CB_CONTINUE;
       }

       Debug( LDAP_DEBUG_TRACE, "==> autogroup_modify_entry <%s>\n", op->o_req_dn.bv_val, 0, 0);
       ldap_pvt_thread_mutex_lock( &agi->agi_mutex );                 

       if ( overlay_entry_get_ov( op, &op->o_req_ndn, NULL, NULL, 0, &e, on ) !=
              LDAP_SUCCESS || e == NULL ) {
              Debug( LDAP_DEBUG_TRACE, "autogroup_modify_entry cannot get entry for <%s>\n", op->o_req_dn.bv_val, 0, 0);
              ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
              return SLAP_CB_CONTINUE;
       }

       /* Must refresh groups if a matching member value is modified OR filter contains memberOf=DN */
       for ( age = agi->agi_entry; age ; age = age->age_next ) {
              autogroup_filter_t   *agf;
              for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
                     if ( agf->agf_anlist ) {
                            Modifications *m;
                            for ( m = op->orm_modlist ; m ; m = m->sml_next ) {
                                   if ( m->sml_desc == agf->agf_anlist[0].an_desc ) {
                                          if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
                                                 int rc = test_filter( op, e, agf->agf_filter );
                                                 if ( rc == LDAP_COMPARE_TRUE ) {
                                                        age->age_mustrefresh = 1;
                                                 }
                                          }
                                   }
                            }
                     }

                     if ( autogroup_memberOf_filter( agf->agf_filter, &op->o_req_ndn, agi->agi_memberof_ad ) ) {
                            age->age_mustrefresh = 1;
                     }
              }
       }

       a = attrs_find( e->e_attrs, slap_schema.si_ad_objectClass );

       if ( a == NULL ) {
              Debug( LDAP_DEBUG_TRACE, "autogroup_modify_entry entry <%s> has no objectClass\n", op->o_req_dn.bv_val, 0, 0);
              ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );        
              return SLAP_CB_CONTINUE;
       }


       for ( ; agd; agd = agd->agd_next ) {

              if ( value_find_ex( slap_schema.si_ad_objectClass,
                            SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
                            SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
                            a->a_nvals, &agd->agd_oc->soc_cname,
                            op->o_tmpmemctx ) == 0 )
              {
                     Modifications *m;
                     int           match = 1;

                     m = op->orm_modlist;

                     for ( age = agi->agi_entry ; age ; age = age->age_next ) {
                            dnMatch( &match, 0, NULL, NULL, &op->o_req_ndn, &age->age_ndn );

                            if ( match == 0 ) {
                                   for ( ; m ; m = m->sml_next ) {
                                          if ( m->sml_desc == age->age_def->agd_member_ad ) {
                                                 overlay_entry_release_ov( op, e, 0, on );
                                                 ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
                                                 Debug( LDAP_DEBUG_TRACE, "autogroup_modify_entry attempted to modify group's <%s> member attribute\n", op->o_req_dn.bv_val, 0, 0);
                                                 send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION, "attempt to modify dynamic group member attribute");
                                                 return LDAP_CONSTRAINT_VIOLATION;
                                          }
                                   }
                                   break;
                            }
                     }

                     overlay_entry_release_ov( op, e, 0, on );
                     ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
                     return SLAP_CB_CONTINUE;
              }
       }

       overlay_entry_release_ov( op, e, 0, on );
       ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );               
       return SLAP_CB_CONTINUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int autogroup_modrdn_entry ( Operation op,
SlapReply rs 
) [static]

Definition at line 1451 of file autogroup.c.

{
       slap_overinst        *on = (slap_overinst *)op->o_bd->bd_info;
       autogroup_info_t     *agi = (autogroup_info_t *)on->on_bi.bi_private;
       autogroup_entry_t    *age;
       Entry                *e;

       if ( get_manageDSAit( op ) ) {
              return SLAP_CB_CONTINUE;
       }

       Debug( LDAP_DEBUG_TRACE, "==> autogroup_modrdn_entry <%s>\n", op->o_req_dn.bv_val, 0, 0);
       ldap_pvt_thread_mutex_lock( &agi->agi_mutex );                 

       if ( overlay_entry_get_ov( op, &op->o_req_ndn, NULL, NULL, 0, &e, on ) !=
              LDAP_SUCCESS || e == NULL ) {
              Debug( LDAP_DEBUG_TRACE, "autogroup_modrdn_entry cannot get entry for <%s>\n", op->o_req_dn.bv_val, 0, 0);
              ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
              return SLAP_CB_CONTINUE;
       }

       /* Must check if a dn is modified */
       for ( age = agi->agi_entry; age ; age = age->age_next ) {
              autogroup_filter_t   *agf;
              for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
                     if ( agf->agf_anlist ) {
                            if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
                                   int rc = test_filter( op, e, agf->agf_filter );
                                   if ( rc == LDAP_COMPARE_TRUE ) {
                                          age->age_modrdn_olddnmodified = 1;
                                   }
                            }
                     }
              }
       }

       overlay_entry_release_ov( op, e, 0, on );
       ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );               
       return SLAP_CB_CONTINUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int autogroup_response ( Operation op,
SlapReply rs 
) [static]

Definition at line 923 of file autogroup.c.

{
       slap_overinst        *on = (slap_overinst *)op->o_bd->bd_info;
       autogroup_info_t     *agi = (autogroup_info_t *)on->on_bi.bi_private;
       autogroup_def_t             *agd = agi->agi_def;
       autogroup_entry_t    *age;
       autogroup_filter_t   *agf;
       BerValue             new_dn, new_ndn, pdn;
       Entry                *e, *group;
       Attribute            *a, *ea;
       int                  is_olddn, is_newdn, is_value_refresh, dn_equal;

       /* Handle all cases where a refresh of the group is needed */
       if ( op->o_tag == LDAP_REQ_DELETE || op->o_tag == LDAP_REQ_MODIFY ) {
              if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !get_manageDSAit( op ) ) {

                     ldap_pvt_thread_mutex_lock( &agi->agi_mutex );

                     for ( age = agi->agi_entry ; age ; age = age->age_next ) {
                            /* Request detected that the group must be refreshed */

                            ldap_pvt_thread_mutex_lock( &age->age_mutex );

                            if ( age->age_mustrefresh ) {
                                   autogroup_delete_member_from_group( op, NULL, NULL, age) ;

                                   for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
                                          autogroup_add_members_from_filter( op, NULL, age, agf, 1 );
                                   }
                            }

                            ldap_pvt_thread_mutex_unlock( &age->age_mutex );
                     }

                     ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
              }
       } else if ( op->o_tag == LDAP_REQ_MODRDN ) {
              if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS && !get_manageDSAit( op )) {

                     Debug( LDAP_DEBUG_TRACE, "==> autogroup_response MODRDN from <%s>\n", op->o_req_dn.bv_val, 0, 0);

                     ldap_pvt_thread_mutex_lock( &agi->agi_mutex );                 

                     if ( op->oq_modrdn.rs_newSup ) {
                            pdn = *op->oq_modrdn.rs_newSup;
                     } else {
                            dnParent( &op->o_req_dn, &pdn );
                     }
                     build_new_dn( &new_dn, &pdn, &op->orr_newrdn, op->o_tmpmemctx );

                     if ( op->oq_modrdn.rs_nnewSup ) {
                            pdn = *op->oq_modrdn.rs_nnewSup;
                     } else {
                            dnParent( &op->o_req_ndn, &pdn );
                     }
                     build_new_dn( &new_ndn, &pdn, &op->orr_nnewrdn, op->o_tmpmemctx );

                     Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN to <%s>\n", new_dn.bv_val, 0, 0);

                     dnMatch( &dn_equal, 0, NULL, NULL, &op->o_req_ndn, &new_ndn );

                     if ( overlay_entry_get_ov( op, &new_ndn, NULL, NULL, 0, &e, on ) !=
                            LDAP_SUCCESS || e == NULL ) {
                            Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN cannot get entry for <%s>\n", new_dn.bv_val, 0, 0);
                            ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
                            return SLAP_CB_CONTINUE;
                     }

                     a = attrs_find( e->e_attrs, slap_schema.si_ad_objectClass );


                     if ( a == NULL ) {
                            Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN entry <%s> has no objectClass\n", new_dn.bv_val, 0, 0);
                            overlay_entry_release_ov( op, e, 0, on );
                            ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );        
                            return SLAP_CB_CONTINUE;
                     }


                     /* If a groups DN is modified, just update age_dn/ndn of that group with the new DN. */
                     for ( ; agd; agd = agd->agd_next ) {

                            if ( value_find_ex( slap_schema.si_ad_objectClass,
                                          SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
                                          SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
                                          a->a_nvals, &agd->agd_oc->soc_cname,
                                          op->o_tmpmemctx ) == 0 )
                            {             
                                   for ( age = agi->agi_entry ; age ; age = age->age_next ) {
                                          int match = 1;

                                          dnMatch( &match, 0, NULL, NULL, &age->age_ndn, &op->o_req_ndn );
                                          if ( match == 0 ) {
                                                 Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN updating group's DN to <%s>\n", new_dn.bv_val, 0, 0);
                                                 ber_dupbv( &age->age_dn, &new_dn );
                                                 ber_dupbv( &age->age_ndn, &new_ndn );

                                                 op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx  );
                                                 op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx );
                                                 overlay_entry_release_ov( op, e, 0, on );
                                                 ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );        
                                                 return SLAP_CB_CONTINUE;
                                          }
                                   }

                            }
                     }

                     /* For each group: 
                        1. check if the orginal entry's DN is in the group.
                        2. chceck if the any of the group filter's base DN is a suffix of the new DN 

                        If 1 and 2 are both false, we do nothing.
                        If 1 and 2 is true, we remove the old DN from the group, and add the new DN.
                        If 1 is false, and 2 is true, we check the entry against the group's filters,
                            and add it's DN to the group.
                        If 1 is true, and 2 is false, we delete the entry's DN from the group.
                     */
                     for ( age = agi->agi_entry ; age ; age = age->age_next ) {
                            is_olddn = 0;
                            is_newdn = 0;
                            is_value_refresh = 0;


                            ldap_pvt_thread_mutex_lock( &age->age_mutex );

                            if ( age->age_filter && age->age_filter->agf_anlist ) {
                                   ea = attrs_find( e->e_attrs, age->age_filter->agf_anlist[0].an_desc );
                            }
                            else {
                                   ea = NULL;
                            }

                            if ( age->age_modrdn_olddnmodified ) {
                                   /* Resquest already marked this group to be updated */
                                   is_olddn = 1;
                                   is_value_refresh = 1;
                                   age->age_modrdn_olddnmodified = 0;
                            } else {

                                   if ( overlay_entry_get_ov( op, &age->age_ndn, NULL, NULL, 0, &group, on ) !=
                                          LDAP_SUCCESS || group == NULL ) {
                                          Debug( LDAP_DEBUG_TRACE, "autogroup_response MODRDN cannot get group entry <%s>\n", age->age_dn.bv_val, 0, 0);

                                          op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx );
                                          op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx );

                                          overlay_entry_release_ov( op, e, 0, on );
                                          ldap_pvt_thread_mutex_unlock( &age->age_mutex );
                                          ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
                                          return SLAP_CB_CONTINUE;
                                   }

                                   a = attrs_find( group->e_attrs, age->age_def->agd_member_ad );

                                   if ( a != NULL ) {
                                          if ( value_find_ex( age->age_def->agd_member_ad,
                                                        SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
                                                        SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
                                                        a->a_nvals, ea ? ea->a_nvals : &op->o_req_ndn, op->o_tmpmemctx ) == 0 ) 
                                          {
                                                 is_olddn = 1;
                                          }

                                   }

                                   overlay_entry_release_ov( op, group, 0, on );

                            }

                            for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
                                   if ( dnIsSuffix( &new_ndn, &agf->agf_ndn ) ) {
                                          /* TODO: should retest filter as it could imply conditions on the dn */
                                          is_newdn = 1;
                                          break;
                                   }
                            }


                            if ( is_value_refresh ) {
                                   if ( is_olddn != is_newdn ) {
                                          /* group refresh */
                                          autogroup_delete_member_from_group( op, NULL, NULL, age) ;

                                          for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
                                                 autogroup_add_members_from_filter( op, NULL, age, agf, 1 );
                                          }
                                   }
                                   ldap_pvt_thread_mutex_unlock( &age->age_mutex );
                                   continue;
                            }
                            if ( is_olddn == 1 && is_newdn == 0 ) {
                                   if ( ea )
                                          autogroup_delete_member_values_from_group( op, e, age, age->age_filter->agf_anlist[0].an_desc );
                                   else
                                          autogroup_delete_member_from_group( op, &op->o_req_dn, &op->o_req_ndn, age );
                            } else
                            if ( is_olddn == 0 && is_newdn == 1 ) {
                                   for ( agf = age->age_filter; agf; agf = agf->agf_next ) {
                                          if ( test_filter( op, e, agf->agf_filter ) == LDAP_COMPARE_TRUE ) {
                                                 if ( ea )
                                                        autogroup_add_member_values_to_group( op, e, age, age->age_filter->agf_anlist[0].an_desc );
                                                 else
                                                        autogroup_add_member_to_group( op, &new_dn, &new_ndn, age );
                                                 break;
                                          }
                                   }
                            } else
                            if ( is_olddn == 1 && is_newdn == 1 && dn_equal != 0 ) {
                                   if ( ea ) {
                                          /* group refresh */
                                          autogroup_delete_member_from_group( op, NULL, NULL, age) ;

                                          for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
                                                 autogroup_add_members_from_filter( op, NULL, age, agf, 1 );
                                          }
                                   }
                                   else {
                                          autogroup_delete_member_from_group( op, &op->o_req_dn, &op->o_req_ndn, age );
                                          autogroup_add_member_to_group( op, &new_dn, &new_ndn, age );
                                   }
                            }

                            ldap_pvt_thread_mutex_unlock( &age->age_mutex );
                     }

                     op->o_tmpfree( new_dn.bv_val, op->o_tmpmemctx );
                     op->o_tmpfree( new_ndn.bv_val, op->o_tmpmemctx );

                     overlay_entry_release_ov( op, e, 0, on );

                     ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );               
              }
       }

       if ( op->o_tag == LDAP_REQ_MODIFY ) {
              if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS  && !get_manageDSAit( op ) ) {
                     Debug( LDAP_DEBUG_TRACE, "==> autogroup_response MODIFY <%s>\n", op->o_req_dn.bv_val, 0, 0);

                     ldap_pvt_thread_mutex_lock( &agi->agi_mutex );                 

                     if ( overlay_entry_get_ov( op, &op->o_req_ndn, NULL, NULL, 0, &e, on ) !=
                            LDAP_SUCCESS || e == NULL ) {
                            Debug( LDAP_DEBUG_TRACE, "autogroup_response MODIFY cannot get entry for <%s>\n", op->o_req_dn.bv_val, 0, 0);
                            ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
                            return SLAP_CB_CONTINUE;
                     }

                     a = attrs_find( e->e_attrs, slap_schema.si_ad_objectClass );


                     if ( a == NULL ) {
                            Debug( LDAP_DEBUG_TRACE, "autogroup_response MODIFY entry <%s> has no objectClass\n", op->o_req_dn.bv_val, 0, 0);
                            overlay_entry_release_ov( op, e, 0, on );
                            ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );        
                            return SLAP_CB_CONTINUE;
                     }

                     /* If we modify a group's memberURL, we have to delete all of it's members,
                        and add them anew, because we cannot tell from which memberURL a member was added. */
                     for ( ; agd; agd = agd->agd_next ) {

                            if ( value_find_ex( slap_schema.si_ad_objectClass,
                                          SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
                                          SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
                                          a->a_nvals, &agd->agd_oc->soc_cname,
                                          op->o_tmpmemctx ) == 0 )
                            {
                                   Modifications *m;
                                   int           match = 1;

                                   m = op->orm_modlist;

                                   for ( age = agi->agi_entry ; age ; age = age->age_next ) {
                                          ldap_pvt_thread_mutex_lock( &age->age_mutex );

                                          dnMatch( &match, 0, NULL, NULL, &op->o_req_ndn, &age->age_ndn );

                                          if ( match == 0 ) {
                                                 for ( ; m ; m = m->sml_next ) {
                                                        if ( m->sml_desc == age->age_def->agd_member_url_ad ) {
                                                               autogroup_def_t      *group_agd = age->age_def;
                                                               Debug( LDAP_DEBUG_TRACE, "autogroup_response MODIFY changing memberURL for group <%s>\n", 
                                                                      op->o_req_dn.bv_val, 0, 0);

                                                               overlay_entry_release_ov( op, e, 0, on );

                                                               autogroup_delete_member_from_group( op, NULL, NULL, age );
                                                               autogroup_delete_group( agi, age );

                                                               autogroup_add_group( op, agi, group_agd, NULL, &op->o_req_ndn, 1, 1);

                                                               overlay_entry_release_ov( op, e, 0, on );
                                                               ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
                                                               return SLAP_CB_CONTINUE;
                                                        }
                                                 }

                                                 ldap_pvt_thread_mutex_unlock( &age->age_mutex );
                                                 break;
                                          }

                                          ldap_pvt_thread_mutex_unlock( &age->age_mutex );
                                   }

                                   overlay_entry_release_ov( op, e, 0, on );
                                   ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
                                   return SLAP_CB_CONTINUE;
                            }
                     }

                     /* When modifing any of the attributes of an entry, we must
                        check if the entry is in any of our groups, and if
                        the modified entry maches any of the filters of that group.

                        If the entry exists in a group, but the modified attributes do
                            not match any of the group's filters, we delete the entry from that group.
                        If the entry doesn't exist in a group, but matches a filter, 
                            we add it to that group.
                     */
                     for ( age = agi->agi_entry ; age ; age = age->age_next ) {
                            is_olddn = 0;
                            is_newdn = 0;


                            ldap_pvt_thread_mutex_lock( &age->age_mutex );

                            if ( age->age_filter && age->age_filter->agf_anlist ) {
                                   ea = attrs_find( e->e_attrs, age->age_filter->agf_anlist[0].an_desc );
                            }
                            else {
                                   ea = NULL;
                            }

                            if ( overlay_entry_get_ov( op, &age->age_ndn, NULL, NULL, 0, &group, on ) !=
                                   LDAP_SUCCESS || group == NULL ) {
                                   Debug( LDAP_DEBUG_TRACE, "autogroup_response MODIFY cannot get entry for <%s>\n", 
                                          age->age_dn.bv_val, 0, 0);

                                   overlay_entry_release_ov( op, e, 0, on );
                                   ldap_pvt_thread_mutex_unlock( &age->age_mutex );
                                   ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
                                   return SLAP_CB_CONTINUE;
                            }

                            a = attrs_find( group->e_attrs, age->age_def->agd_member_ad );

                            if ( a != NULL ) {
                                   if ( value_find_ex( age->age_def->agd_member_ad,
                                                 SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
                                                 SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
                                                 a->a_nvals, ea ? ea->a_nvals : &op->o_req_ndn, op->o_tmpmemctx ) == 0 ) 
                                   {
                                          is_olddn = 1;
                                   }

                            }

                            overlay_entry_release_ov( op, group, 0, on );

                            for ( agf = age->age_filter ; agf ; agf = agf->agf_next ) {
                                   if ( dnIsSuffix( &op->o_req_ndn, &agf->agf_ndn ) ) {
                                          if ( test_filter( op, e, agf->agf_filter ) == LDAP_COMPARE_TRUE ) {
                                                 is_newdn = 1;
                                                 break;
                                          }
                                   }
                            }

                            if ( is_olddn == 1 && is_newdn == 0 ) {
                                   if(ea)
                                          autogroup_delete_member_values_from_group( op, e, age, age->age_filter->agf_anlist[0].an_desc );
                                   else
                                          autogroup_delete_member_from_group( op, &op->o_req_dn, &op->o_req_ndn, age );
                            } else
                            if ( is_olddn == 0 && is_newdn == 1 ) {
                                   if(ea)
                                          autogroup_add_member_values_to_group( op, e, age, age->age_filter->agf_anlist[0].an_desc );
                                   else
                                          autogroup_add_member_to_group( op, &op->o_req_dn, &op->o_req_ndn, age );
                            } 

                            ldap_pvt_thread_mutex_unlock( &age->age_mutex );
                     }

                     overlay_entry_release_ov( op, e, 0, on );

                     ldap_pvt_thread_mutex_unlock( &agi->agi_mutex );
              }
       }

       return SLAP_CB_CONTINUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int init_module ( int  argc,
char *  argv[] 
)

Definition at line 2048 of file autogroup.c.

{
       return autogroup_initialize();
}

Here is the call graph for this function:


Variable Documentation

Definition at line 1527 of file autogroup.c.

ConfigTable agcfg[] [static]
Initial value:
 {
       { "autogroup-attrset", "group-oc> <URL-ad> <member-ad",
              3, 4, 0, ARG_MAGIC|AG_ATTRSET, ag_cfgen,
              "( OLcfgCtAt:2.1 NAME 'olcAGattrSet' "
                     "DESC 'Automatic groups: <group objectClass>, <URL attributeDescription>, <member attributeDescription>' "
                     "EQUALITY caseIgnoreMatch "
                     "SYNTAX OMsDirectoryString "
                     "X-ORDERED 'VALUES' )",
                     NULL, NULL },
       
       { "autogroup-memberof-ad", "memberOf attribute",
              2, 2, 0, ARG_MAGIC|AG_MEMBER_OF_AD, ag_cfgen,
              "( OLcfgCtAt:2.2 NAME 'olcAGmemberOfAd' "
                     "DESC 'memberOf attribute' "
                     "SYNTAX OMsDirectoryString SINGLE-VALUE )",
                     NULL, NULL },

       { NULL, NULL, 0, 0, 0, ARG_IGNORED }
}

Definition at line 1529 of file autogroup.c.

ConfigOCs agocs[] [static]
Initial value:
 {
       { "( OLcfgCtOc:2.1 "
              "NAME 'olcAutomaticGroups' "
              "DESC 'Automatic groups configuration' "
              "SUP olcOverlayConfig "
              "MAY ( "
                     "olcAGattrSet "
                     "$ olcAGmemberOfAd "
                  ")"
         ")",
              Cft_Overlay, agcfg, NULL, NULL },
       { NULL, 0, NULL }
}

Definition at line 1549 of file autogroup.c.

slap_overinst autogroup = { { NULL } } [static]

Definition at line 2017 of file autogroup.c.

Definition at line 68 of file init.c.