static int dynlist_make_filter( Operation *op, struct berval *oldf, struct berval *newf ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; dynlist_info_t *dli = (dynlist_info_t *)on->on_bi.bi_private; char *ptr; assert( oldf != NULL ); assert( newf != NULL ); assert( !BER_BVISNULL( oldf ) ); assert( !BER_BVISEMPTY( oldf ) ); newf->bv_len = STRLENOF( "(&(!(objectClass=" "))" ")" ) + dli->dli_oc->soc_cname.bv_len + oldf->bv_len; newf->bv_val = op->o_tmpalloc( newf->bv_len + 1, op->o_tmpmemctx ); if ( newf->bv_val == NULL ) { return -1; } ptr = lutil_strcopy( newf->bv_val, "(&(!(objectClass=" ); ptr = lutil_strcopy( ptr, dli->dli_oc->soc_cname.bv_val ); ptr = lutil_strcopy( ptr, "))" ); ptr = lutil_strcopy( ptr, oldf->bv_val ); ptr = lutil_strcopy( ptr, ")" ); newf->bv_len = ptr - newf->bv_val; return 0; }
static int pg_dynacl_unparse( void *priv, struct berval *bv ) { pg_t *pg = (pg_t *)priv; char *ptr; bv->bv_len = STRLENOF( " dynacl/posixGroup.expand=" ) + pg->pg_pat.bv_len; bv->bv_val = ch_malloc( bv->bv_len + 1 ); ptr = lutil_strcopy( bv->bv_val, " dynacl/posixGroup" ); switch ( pg->pg_style ) { case ACL_STYLE_BASE: ptr = lutil_strcopy( ptr, ".exact=" ); break; case ACL_STYLE_EXPAND: ptr = lutil_strcopy( ptr, ".expand=" ); break; default: assert( 0 ); } ptr = lutil_strncopy( ptr, pg->pg_pat.bv_val, pg->pg_pat.bv_len ); ptr[ 0 ] = '\0'; bv->bv_len = ptr - bv->bv_val; return 0; }
static char * rwm_suffix_massage_patternize( const char *s, const char *p ) { ber_len_t len; char *res, *ptr; len = strlen( p ); if ( s[ 0 ] == '\0' ) { len++; } res = ch_calloc( sizeof( char ), len + STRLENOF( "%1" ) + 1 ); if ( res == NULL ) { return NULL; } ptr = lutil_strcopy( res, ( p[0] == '\0' ? "%2" : "%1" ) ); if ( s[ 0 ] == '\0' ) { ptr[ 0 ] = ','; ptr++; } lutil_strcopy( ptr, p ); return res; }
int perl_back_compare( Operation *op, SlapReply *rs ) { int count; char *avastr; PerlBackend *perl_back = (PerlBackend *)op->o_bd->be_private; avastr = ch_malloc( op->orc_ava->aa_desc->ad_cname.bv_len + 1 + op->orc_ava->aa_value.bv_len + 1 ); lutil_strcopy( lutil_strcopy( lutil_strcopy( avastr, op->orc_ava->aa_desc->ad_cname.bv_val ), "=" ), op->orc_ava->aa_value.bv_val ); #if defined(HAVE_WIN32_ASPERL) || defined(USE_ITHREADS) PERL_SET_CONTEXT( PERL_INTERPRETER ); #endif ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex ); { dSP; ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs( perl_back->pb_obj_ref ); XPUSHs(sv_2mortal(newSVpv( op->o_req_dn.bv_val , 0))); XPUSHs(sv_2mortal(newSVpv( avastr , 0))); PUTBACK; #ifdef PERL_IS_5_6 count = call_method("compare", G_SCALAR); #else count = perl_call_method("compare", G_SCALAR); #endif SPAGAIN; if (count != 1) { croak("Big trouble in back_compare\n"); } rs->sr_err = POPi; PUTBACK; FREETMPS; LEAVE; } ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex ); ch_free( avastr ); send_ldap_result( op, rs ); Debug( LDAP_DEBUG_ANY, "Perl COMPARE\n", 0, 0, 0 ); return (0); }
/* This function constructs a full DN for a given entry. */ int hdb_fix_dn( Entry *e, int checkit ) { EntryInfo *ei; int rlen = 0, nrlen = 0; char *ptr, *nptr; int max = 0; if ( !e->e_id ) return 0; /* count length of all DN components */ for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) { rlen += ei->bei_rdn.bv_len + 1; nrlen += ei->bei_nrdn.bv_len + 1; if (ei->bei_modrdns > max) max = ei->bei_modrdns; } /* See if the entry DN was invalidated by a subtree rename */ if ( checkit ) { if ( BEI(e)->bei_modrdns >= max ) { return 0; } /* We found a mismatch, tell the caller to lock it */ if ( checkit == 1 ) { return 1; } /* checkit == 2. do the fix. */ free( e->e_name.bv_val ); free( e->e_nname.bv_val ); } e->e_name.bv_len = rlen - 1; e->e_nname.bv_len = nrlen - 1; e->e_name.bv_val = ch_malloc(rlen); e->e_nname.bv_val = ch_malloc(nrlen); ptr = e->e_name.bv_val; nptr = e->e_nname.bv_val; for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) { ptr = lutil_strcopy(ptr, ei->bei_rdn.bv_val); nptr = lutil_strcopy(nptr, ei->bei_nrdn.bv_val); if ( ei->bei_parent ) { *ptr++ = ','; *nptr++ = ','; } } BEI(e)->bei_modrdns = max; if ( ptr > e->e_name.bv_val ) ptr[-1] = '\0'; if ( nptr > e->e_nname.bv_val ) nptr[-1] = '\0'; return 0; }
static int idattr_dynacl_unparse_selfattr(idattr_t *id, char **ace) { if (id == NULL || ace == NULL || *ace == NULL) return -1; if (!BER_BVISNULL(&id->idattr_selfattr)) { *ace = lutil_strcopy( *ace, "SELFATTR:" ); *ace = lutil_strcopy( *ace, id->idattr_selfattr.bv_val ); *ace = lutil_strcopy( *ace, ";" ); } return 0; }
static int idattr_dynacl_unparse_applyto(idattr_t *id, char **ace) { if (id == NULL || ace == NULL || *ace == NULL) return -1; if (!BER_BVISNULL(&id->idattr_applyto_uuid)) { *ace = lutil_strcopy( *ace, "APPLYTO:" ); *ace = lutil_strcopy( *ace, id->idattr_applyto_uuid.bv_val ); *ace = lutil_strcopy( *ace, ";" ); } return 0; }
static int dynacl_aci_unparse( void *priv, struct berval *bv ) { AttributeDescription *ad = ( AttributeDescription * )priv; char *ptr; assert( ad != NULL ); bv->bv_val = ch_malloc( STRLENOF(" aci=") + ad->ad_cname.bv_len + 1 ); ptr = lutil_strcopy( bv->bv_val, " aci=" ); ptr = lutil_strcopy( ptr, ad->ad_cname.bv_val ); bv->bv_len = ptr - bv->bv_val; return 0; }
extern "C" int ndb_aset_create( struct ndb_info *ni, NdbOcInfo *oci ) { char buf[4096], *ptr; NdbAttrInfo *ai; int i; ptr = buf + sprintf( buf, "CREATE TABLE IF NOT EXISTS `%s` (eid bigint unsigned NOT NULL, vid int unsigned NOT NULL", oci->no_table.bv_val ); for ( i=0; i<oci->no_nattrs; i++ ) { if ( oci->no_attrs[i]->na_oi != oci ) continue; ai = oci->no_attrs[i]; ptr += sprintf( ptr, ", `%s` VARCHAR(%d)", ai->na_attr->sat_cname.bv_val, ai->na_len ); if ( ai->na_flag & NDB_INFO_INDEX ) { ptr += sprintf( ptr, ", INDEX (`%s`)", ai->na_attr->sat_cname.bv_val ); } } ptr = lutil_strcopy( ptr, ", PRIMARY KEY(eid, vid) ) ENGINE=ndb PARTITION BY KEY(eid)" ); i = mysql_real_query( &ni->ni_sql, buf, ptr - buf ); if ( i ) { Debug( LDAP_DEBUG_ANY, "ndb_aset_create: CREATE TABLE %s failed, %s (%d)\n", oci->no_table.bv_val, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); } return i; }
static int idattr_dynacl_unparse_style(idattr_t *id, char **ace) { if (id == NULL || ace == NULL || *ace == NULL) return -1; switch ( id->idattr_style ) { case ACL_STYLE_BASE: *ace = lutil_strcopy( *ace, ".exact=" ); break; case ACL_STYLE_EXPAND: *ace = lutil_strcopy( *ace, ".expand=" ); break; default: break; } return 0; }
void slapi_int_plugin_unparse( Backend *be, BerVarray *out ) { Slapi_PBlock *pp; int i, j; char **argv, ibuf[32], *ptr; struct berval idx, bv; *out = NULL; idx.bv_val = ibuf; i = 0; for ( pp = SLAPI_BACKEND_PBLOCK( be ); pp != NULL; slapi_pblock_get( pp, SLAPI_IBM_PBLOCK, &pp ) ) { slapi_pblock_get( pp, SLAPI_X_CONFIG_ARGV, &argv ); if ( argv == NULL ) /* could be dynamic plugin */ continue; idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), "{%d}", i ); if ( idx.bv_len >= sizeof( ibuf ) ) { /* FIXME: just truncating by now */ idx.bv_len = sizeof( ibuf ) - 1; } bv.bv_len = idx.bv_len; for (j=1; argv[j]; j++) { bv.bv_len += strlen(argv[j]); if ( j ) bv.bv_len++; } bv.bv_val = ch_malloc( bv.bv_len + 1 ); ptr = lutil_strcopy( bv.bv_val, ibuf ); for (j=1; argv[j]; j++) { if ( j ) *ptr++ = ' '; ptr = lutil_strcopy( ptr, argv[j] ); } ber_bvarray_add( out, &bv ); } }
static int gssattr_dynacl_unparse( void *priv, struct berval *bv ) { gssattr_t *gssattr = (gssattr_t *)priv; char *ptr; bv->bv_len = STRLENOF( " dynacl/gss/.expand=" ) + gssattr->gssattr_name.bv_len + gssattr->gssattr_value.bv_len; bv->bv_val = ch_malloc( bv->bv_len + 1 ); ptr = lutil_strcopy( bv->bv_val, " dynacl/gss/" ); ptr = lutil_strncopy( ptr, gssattr->gssattr_name.bv_val, gssattr->gssattr_name.bv_len ); switch ( gssattr->gssattr_style ) { case ACL_STYLE_BASE: ptr = lutil_strcopy( ptr, ".exact=" ); break; case ACL_STYLE_REGEX: ptr = lutil_strcopy( ptr, ".regex=" ); break; case ACL_STYLE_EXPAND: ptr = lutil_strcopy( ptr, ".expand=" ); break; default: assert( 0 ); break; } ptr = lutil_strncopy( ptr, gssattr->gssattr_value.bv_val, gssattr->gssattr_value.bv_len ); ptr[ 0 ] = '\0'; bv->bv_len = ptr - bv->bv_val; return 0; }
static int dynlist_build_def_filter( dynlist_info_t *dli ) { char *ptr; dli->dli_default_filter.bv_len = STRLENOF( "(!(objectClass=" "))" ) + dli->dli_oc->soc_cname.bv_len; dli->dli_default_filter.bv_val = ch_malloc( dli->dli_default_filter.bv_len + 1 ); if ( dli->dli_default_filter.bv_val == NULL ) { Debug( LDAP_DEBUG_ANY, "dynlist_db_open: malloc failed.\n", 0, 0, 0 ); return -1; } ptr = lutil_strcopy( dli->dli_default_filter.bv_val, "(!(objectClass=" ); ptr = lutil_strcopy( ptr, dli->dli_oc->soc_cname.bv_val ); ptr = lutil_strcopy( ptr, "))" ); assert( ptr == &dli->dli_default_filter.bv_val[dli->dli_default_filter.bv_len] ); return 0; }
static int idattr_dynacl_unparse_optionsavailable(idattr_t *id, char **ace) { if (id == NULL || ace == NULL || *ace == NULL) return -1; if ((id->idattr_ops != 0) || !BER_BVISNULL(&id->idattr_applyto_uuid) || !BER_BVISNULL(&id->idattr_selfattr) || !BER_BVISNULL(&id->idattr_boolattr)) { *ace = lutil_strcopy( *ace, "/" ); } return 0; }
static char * rwm_suffix_massage_regexize( const char *s ) { char *res, *ptr; const char *p, *r; int i; if ( s[0] == '\0' ) { return ch_strdup( "^(.+)$" ); } for ( i = 0, p = s; ( r = strchr( p, ',' ) ) != NULL; p = r + 1, i++ ) ; res = ch_calloc( sizeof( char ), strlen( s ) + STRLENOF( "((.+),)?" ) + STRLENOF( "[ ]?" ) * i + STRLENOF( "$" ) + 1 ); ptr = lutil_strcopy( res, "((.+),)?" ); for ( i = 0, p = s; ( r = strchr( p, ',' ) ) != NULL; p = r + 1 , i++ ) { ptr = lutil_strncopy( ptr, p, r - p + 1 ); ptr = lutil_strcopy( ptr, "[ ]?" ); if ( r[ 1 ] == ' ' ) { r++; } } ptr = lutil_strcopy( ptr, p ); ptr[0] = '$'; ptr[1] = '\0'; return res; }
/* This function constructs a full DN for a given id. We really should * be passing idNodes directly, to save some effort... */ int bdb_fix_dn( BackendDB *be, ID id, Entry *e ) { struct bdb_info *bdb = (struct bdb_info *) be->be_private; idNode *n, *o; int rlen, nrlen; char *ptr, *nptr; ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr); o = bdb_find_id_node(id, bdb->bi_tree); rlen = be->be_suffix[0].bv_len + 1; nrlen = be->be_nsuffix[0].bv_len + 1; for (n = o; n && n->i_parent; n=n->i_parent) { rlen += n->i_rdn->rdn.bv_len + 1; nrlen += n->i_rdn->nrdn.bv_len + 1; } e->e_name.bv_len = rlen - 1; e->e_nname.bv_len = nrlen - 1; e->e_name.bv_val = ch_malloc(rlen + nrlen); e->e_nname.bv_val = e->e_name.bv_val + rlen; ptr = e->e_name.bv_val; nptr = e->e_nname.bv_val; for (n = o; n && n->i_parent; n=n->i_parent) { ptr = lutil_strcopy(ptr, n->i_rdn->rdn.bv_val); *ptr++ = ','; nptr = lutil_strcopy(nptr, n->i_rdn->nrdn.bv_val); *nptr++ = ','; } ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr); strcpy(ptr, be->be_suffix[0].bv_val); strcpy(nptr, be->be_nsuffix[0].bv_val); return 0; }
void slapd_slp_init( const char* urls ) { int i; slapd_srvurls = ldap_str2charray( urls, " " ); if( slapd_srvurls == NULL ) return; /* find and expand INADDR_ANY URLs */ for( i=0; slapd_srvurls[i] != NULL; i++ ) { if( strcmp( slapd_srvurls[i], "ldap:///" ) == 0) { char *host = ldap_pvt_get_fqdn( NULL ); if ( host != NULL ) { slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i], strlen( host ) + sizeof( LDAP_SRVTYPE_PREFIX ) ); strcpy( lutil_strcopy(slapd_srvurls[i], LDAP_SRVTYPE_PREFIX ), host ); ch_free( host ); } } else if ( strcmp( slapd_srvurls[i], "ldaps:///" ) == 0) { char *host = ldap_pvt_get_fqdn( NULL ); if ( host != NULL ) { slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i], strlen( host ) + sizeof( LDAPS_SRVTYPE_PREFIX ) ); strcpy( lutil_strcopy(slapd_srvurls[i], LDAPS_SRVTYPE_PREFIX ), host ); ch_free( host ); } } } /* open the SLP handle */ SLPOpen( "en", 0, &slapd_hslp ); }
static int dynlist_make_filter( Operation *op, Entry *e, const char *url, struct berval *oldf, struct berval *newf ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; dynlist_info_t *dli = (dynlist_info_t *)on->on_bi.bi_private; char *ptr; int needBrackets = 0; assert( oldf != NULL ); assert( newf != NULL ); assert( !BER_BVISNULL( oldf ) ); assert( !BER_BVISEMPTY( oldf ) ); if ( oldf->bv_val[0] != '(' ) { Debug( LDAP_DEBUG_ANY, "%s: dynlist, DN=\"%s\": missing brackets in URI=\"%s\" filter\n", op->o_log_prefix, e->e_name.bv_val, url ); needBrackets = 2; } newf->bv_len = STRLENOF( "(&(!(objectClass=" "))" ")" ) + dli->dli_oc->soc_cname.bv_len + oldf->bv_len + needBrackets; newf->bv_val = op->o_tmpalloc( newf->bv_len + 1, op->o_tmpmemctx ); if ( newf->bv_val == NULL ) { return -1; } ptr = lutil_strcopy( newf->bv_val, "(&(!(objectClass=" ); ptr = lutil_strcopy( ptr, dli->dli_oc->soc_cname.bv_val ); ptr = lutil_strcopy( ptr, "))" ); if ( needBrackets ) *ptr++ = '('; ptr = lutil_strcopy( ptr, oldf->bv_val ); if ( needBrackets ) *ptr++ = ')'; ptr = lutil_strcopy( ptr, ")" ); newf->bv_len = ptr - newf->bv_val; return 0; }
static int ndb_oc_create( struct ndb_info *ni, NdbOcInfo *oci, int create ) { char buf[4096], *ptr; int i, rc = 0, col; if ( create ) { ptr = buf + sprintf( buf, "CREATE TABLE `%s` (eid bigint unsigned NOT NULL, vid int unsigned NOT NULL", oci->no_table.bv_val ); } col = 0; if ( oci->no_oc->soc_required ) { for ( i=0; oci->no_oc->soc_required[i]; i++ ); col += i; } if ( oci->no_oc->soc_allowed ) { for ( i=0; oci->no_oc->soc_allowed[i]; i++ ); col += i; } /* assume all are present */ oci->no_attrs = (struct ndb_attrinfo **)ch_malloc( col * sizeof(struct ndb_attrinfo *)); col = 2; ldap_pvt_thread_rdwr_wlock( &ni->ni_ai_rwlock ); if ( oci->no_oc->soc_required ) { rc = ndb_ai_check( ni, oci, oci->no_oc->soc_required, &ptr, &col, create ); } if ( !rc && oci->no_oc->soc_allowed ) { rc = ndb_ai_check( ni, oci, oci->no_oc->soc_allowed, &ptr, &col, create ); } ldap_pvt_thread_rdwr_wunlock( &ni->ni_ai_rwlock ); /* shrink down to just the needed size */ oci->no_attrs = (struct ndb_attrinfo **)ch_realloc( oci->no_attrs, oci->no_nattrs * sizeof(struct ndb_attrinfo *)); if ( create ) { ptr = lutil_strcopy( ptr, ", PRIMARY KEY(eid, vid) ) ENGINE=ndb PARTITION BY KEY(eid)" ); rc = mysql_real_query( &ni->ni_sql, buf, ptr - buf ); if ( rc ) { Debug( LDAP_DEBUG_ANY, "ndb_oc_create: CREATE TABLE %s failed, %s (%d)\n", oci->no_table.bv_val, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) ); } } return rc; }
/* ** Builds a filter for searching for the ** group entries, according to the objectClass. */ static int autogroup_build_def_filter( autogroup_def_t *agd, Operation *op ) { 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; }
/* caller must provide buffer space, after calling index2bvlen */ void slap_index2bv( slap_mask_t idx, struct berval *bv ) { int i; char *ptr; if ( !bv->bv_len ) return; ptr = bv->bv_val; for ( i=0; !BER_BVISNULL( &idxstr[i].word ); i++ ) { if ( !idxstr[i].mask ) continue; if ( IS_SLAP_INDEX( idx, idxstr[i].mask )) { if ( (idxstr[i].mask & SLAP_INDEX_SUBSTR) && ((idx & SLAP_INDEX_SUBSTR_DEFAULT) != idxstr[i].mask)) continue; if ( ptr != bv->bv_val ) *ptr++ = ','; ptr = lutil_strcopy( ptr, idxstr[i].word.bv_val ); } } }
void build_new_dn( struct berval * new_dn, struct berval * parent_dn, struct berval * newrdn ) { char *ptr; if ( parent_dn == NULL ) { ber_dupbv( new_dn, newrdn ); return; } new_dn->bv_len = parent_dn->bv_len + newrdn->bv_len + 1; new_dn->bv_val = (char *) ch_malloc( new_dn->bv_len + 1 ); ptr = lutil_strcopy( new_dn->bv_val, newrdn->bv_val ); *ptr++ = ','; strcpy( ptr, parent_dn->bv_val ); }
static int idattr_dynacl_unparse( void *priv, struct berval *bv ) { idattr_t *id = (idattr_t *)priv; char *ptr = NULL, *start = NULL; size_t len = 0; bv->bv_len = MAX_ACE_LEN; bv->bv_val = ch_calloc( 1, bv->bv_len + 1 ); start = ptr = lutil_strcopy( bv->bv_val, " dynacl/idattr" ); if (idattr_dynacl_unparse_optionsavailable(id, &ptr) != 0) goto exit_on_error; if (idattr_dynacl_unparse_operation(id, &ptr) != 0) goto exit_on_error; if (idattr_dynacl_unparse_applyto(id, &ptr) != 0) goto exit_on_error; if (idattr_dynacl_unparse_selfattr(id, &ptr) != 0) goto exit_on_error; if (idattr_dynacl_unparse_boolattr(id, &ptr) != 0) goto exit_on_error; // remove trailing option terminator len = strlen(start); if (len && start[len - 1] == ';') { start[len - 1] = '\0'; ptr = start + len - 1; } if (idattr_dynacl_unparse_style(id, &ptr) != 0) goto exit_on_error; ptr = lutil_strncopy( ptr, id->idattr_pat.bv_val, id->idattr_pat.bv_len ); ptr[ 0 ] = '\0'; bv->bv_len = ptr - bv->bv_val; exit_on_error: return 0; }
static int bdb_attr_index_unparser( void *v1, void *v2 ) { AttrInfo *ai = v1; BerVarray *bva = v2; struct berval bv; char *ptr; slap_index2bvlen( ai->ai_indexmask, &bv ); if ( bv.bv_len ) { bv.bv_len += ai->ai_desc->ad_cname.bv_len + 1; ptr = ch_malloc( bv.bv_len+1 ); bv.bv_val = lutil_strcopy( ptr, ai->ai_desc->ad_cname.bv_val ); *bv.bv_val++ = ' '; slap_index2bv( ai->ai_indexmask, &bv ); bv.bv_val = ptr; ber_bvarray_add( bva, &bv ); } return 0; }
static int ndb_cf_gen( ConfigArgs *c ) { struct ndb_info *ni = (struct ndb_info *)c->be->be_private; int i, rc; NdbAttrInfo *ai; NdbOcInfo *oci; ListNode *ln, **l2; struct berval bv, *bva; if ( c->op == SLAP_CONFIG_EMIT ) { char buf[BUFSIZ]; rc = 0; bv.bv_val = buf; switch( c->type ) { case NDB_ATLEN: if ( ni->ni_attrlens ) { for ( ln = ni->ni_attrlens; ln; ln=ln->ln_next ) { ai = (NdbAttrInfo *)ln->ln_data; bv.bv_len = snprintf( buf, sizeof(buf), "%s %d", ai->na_name.bv_val, ai->na_len ); value_add_one( &c->rvalue_vals, &bv ); } } else { rc = 1; } break; case NDB_ATSET: if ( ni->ni_attrsets ) { char *ptr, *end = buf+sizeof(buf); for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) { oci = (NdbOcInfo *)ln->ln_data; ptr = lutil_strcopy( buf, oci->no_name.bv_val ); *ptr++ = ' '; for ( i=0; i<oci->no_nattrs; i++ ) { if ( end - ptr < oci->no_attrs[i]->na_name.bv_len+1 ) break; if ( i ) *ptr++ = ','; ptr = lutil_strcopy(ptr, oci->no_attrs[i]->na_name.bv_val ); } bv.bv_len = ptr - buf; value_add_one( &c->rvalue_vals, &bv ); } } else { rc = 1; } break; case NDB_INDEX: if ( ni->ni_attridxs ) { for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) { ai = (NdbAttrInfo *)ln->ln_data; value_add_one( &c->rvalue_vals, &ai->na_name ); } } else { rc = 1; } break; case NDB_ATBLOB: if ( ni->ni_attrblobs ) { for ( ln = ni->ni_attrblobs; ln; ln=ln->ln_next ) { ai = (NdbAttrInfo *)ln->ln_data; value_add_one( &c->rvalue_vals, &ai->na_name ); } } else { rc = 1; } break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */ rc = 0; switch( c->type ) { case NDB_INDEX: if ( c->valx == -1 ) { /* delete all */ } else { } break; } return rc; } switch( c->type ) { case NDB_ATLEN: ber_str2bv( c->argv[1], 0, 0, &bv ); ai = ndb_ai_get( ni, &bv ); if ( !ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } for ( ln = ni->ni_attrlens; ln; ln = ln->ln_next ) { if ( ln->ln_data == (void *)ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr len already set for %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } } ai->na_len = atoi( c->argv[2] ); ai->na_flag |= NDB_INFO_ATLEN; ln = (ListNode *)ch_malloc( sizeof(ListNode)); ln->ln_data = ai; ln->ln_next = NULL; for ( l2 = &ni->ni_attrlens; *l2; l2 = &(*l2)->ln_next ); *l2 = ln; break; case NDB_INDEX: ber_str2bv( c->argv[1], 0, 0, &bv ); ai = ndb_ai_get( ni, &bv ); if ( !ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } for ( ln = ni->ni_attridxs; ln; ln = ln->ln_next ) { if ( ln->ln_data == (void *)ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr index already set for %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } } ai->na_flag |= NDB_INFO_INDEX; ln = (ListNode *)ch_malloc( sizeof(ListNode)); ln->ln_data = ai; ln->ln_next = NULL; for ( l2 = &ni->ni_attridxs; *l2; l2 = &(*l2)->ln_next ); *l2 = ln; break; case NDB_ATSET: ber_str2bv( c->argv[1], 0, 0, &bv ); bva = ndb_str2bvarray( c->argv[2], strlen( c->argv[2] ), ',', NULL ); rc = ndb_aset_get( ni, &bv, bva, &oci ); ber_bvarray_free( bva ); if ( rc ) { if ( rc == LDAP_ALREADY_EXISTS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attrset %s already defined", c->log, c->argv[1] ); } else { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attrset %s (%d)", c->log, c->argv[1], rc ); } Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } ln = (ListNode *)ch_malloc( sizeof(ListNode)); ln->ln_data = oci; ln->ln_next = NULL; for ( l2 = &ni->ni_attrsets; *l2; l2 = &(*l2)->ln_next ); *l2 = ln; break; case NDB_ATBLOB: ber_str2bv( c->argv[1], 0, 0, &bv ); ai = ndb_ai_get( ni, &bv ); if ( !ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } for ( ln = ni->ni_attrblobs; ln; ln = ln->ln_next ) { if ( ln->ln_data == (void *)ai ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr blob already set for %s", c->log, c->argv[1] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } } ai->na_flag |= NDB_INFO_ATBLOB; ln = (ListNode *)ch_malloc( sizeof(ListNode)); ln->ln_data = ai; ln->ln_next = NULL; for ( l2 = &ni->ni_attrblobs; *l2; l2 = &(*l2)->ln_next ); *l2 = ln; break; } return 0; }
static int sql_cf_gen( ConfigArgs *c ) { backsql_info *bi = (backsql_info *)c->be->be_private; int rc = 0; if ( c->op == SLAP_CONFIG_EMIT ) { switch( c->type ) { case BSQL_CONCAT_PATT: if ( bi->sql_concat_patt ) { c->value_string = ch_strdup( bi->sql_concat_patt ); } else { rc = 1; } break; case BSQL_CREATE_NEEDS_SEL: if ( bi->sql_flags & BSQLF_CREATE_NEEDS_SELECT ) c->value_int = 1; break; case BSQL_UPPER_NEEDS_CAST: if ( bi->sql_flags & BSQLF_UPPER_NEEDS_CAST ) c->value_int = 1; break; case BSQL_HAS_LDAPINFO_DN_RU: if ( !(bi->sql_flags & BSQLF_DONTCHECK_LDAPINFO_DN_RU) ) return 1; if ( bi->sql_flags & BSQLF_HAS_LDAPINFO_DN_RU ) c->value_int = 1; break; case BSQL_FAIL_IF_NO_MAPPING: if ( bi->sql_flags & BSQLF_FAIL_IF_NO_MAPPING ) c->value_int = 1; break; case BSQL_ALLOW_ORPHANS: if ( bi->sql_flags & BSQLF_ALLOW_ORPHANS ) c->value_int = 1; break; case BSQL_SUBTREE_SHORTCUT: if ( bi->sql_flags & BSQLF_USE_SUBTREE_SHORTCUT ) c->value_int = 1; break; case BSQL_FETCH_ALL_ATTRS: if ( bi->sql_flags & BSQLF_FETCH_ALL_ATTRS ) c->value_int = 1; break; case BSQL_CHECK_SCHEMA: if ( bi->sql_flags & BSQLF_CHECK_SCHEMA ) c->value_int = 1; break; case BSQL_AUTOCOMMIT: if ( bi->sql_flags & BSQLF_AUTOCOMMIT_ON ) c->value_int = 1; break; case BSQL_BASE_OBJECT: if ( bi->sql_base_ob_file ) { c->value_string = ch_strdup( bi->sql_base_ob_file ); } else if ( bi->sql_baseObject ) { c->value_string = ch_strdup( "TRUE" ); } else { rc = 1; } break; case BSQL_LAYER: if ( bi->sql_api ) { backsql_api *ba; struct berval bv; char *ptr; int i; for ( ba = bi->sql_api; ba; ba = ba->ba_next ) { bv.bv_len = strlen( ba->ba_name ); if ( ba->ba_argc ) { for ( i = 0; i<ba->ba_argc; i++ ) bv.bv_len += strlen( ba->ba_argv[i] ) + 3; } bv.bv_val = ch_malloc( bv.bv_len + 1 ); ptr = lutil_strcopy( bv.bv_val, ba->ba_name ); if ( ba->ba_argc ) { for ( i = 0; i<ba->ba_argc; i++ ) { *ptr++ = ' '; *ptr++ = '"'; ptr = lutil_strcopy( ptr, ba->ba_argv[i] ); *ptr++ = '"'; } } ber_bvarray_add( &c->rvalue_vals, &bv ); } } else { rc = 1; } break; case BSQL_ALIASING_KEYWORD: if ( !BER_BVISNULL( &bi->sql_aliasing )) { struct berval bv; bv = bi->sql_aliasing; bv.bv_len--; value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } break; case BSQL_FETCH_ATTRS: if ( bi->sql_anlist || ( bi->sql_flags & (BSQLF_FETCH_ALL_USERATTRS| BSQLF_FETCH_ALL_OPATTRS))) { char buf[BUFSIZ*2], *ptr; struct berval bv; # define WHATSLEFT ((ber_len_t) (&buf[sizeof( buf )] - ptr)) ptr = buf; if ( bi->sql_anlist ) { ptr = anlist_unparse( bi->sql_anlist, ptr, WHATSLEFT ); if ( ptr == NULL ) return 1; } if ( bi->sql_flags & BSQLF_FETCH_ALL_USERATTRS ) { if ( WHATSLEFT <= STRLENOF( ",*" )) return 1; if ( ptr != buf ) *ptr++ = ','; *ptr++ = '*'; } if ( bi->sql_flags & BSQLF_FETCH_ALL_OPATTRS ) { if ( WHATSLEFT <= STRLENOF( ",+" )) return 1; if ( ptr != buf ) *ptr++ = ','; *ptr++ = '+'; } bv.bv_val = buf; bv.bv_len = ptr - buf; value_add_one( &c->rvalue_vals, &bv ); } break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */ return -1; } switch( c->type ) { case BSQL_CONCAT_PATT: if ( backsql_split_pattern( c->argv[ 1 ], &bi->sql_concat_func, 2 ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: unable to parse pattern \"%s\"", c->log, c->argv[ 1 ] ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } bi->sql_concat_patt = c->value_string; break; case BSQL_CREATE_NEEDS_SEL: if ( c->value_int ) bi->sql_flags |= BSQLF_CREATE_NEEDS_SELECT; else bi->sql_flags &= ~BSQLF_CREATE_NEEDS_SELECT; break; case BSQL_UPPER_NEEDS_CAST: if ( c->value_int ) bi->sql_flags |= BSQLF_UPPER_NEEDS_CAST; else bi->sql_flags &= ~BSQLF_UPPER_NEEDS_CAST; break; case BSQL_HAS_LDAPINFO_DN_RU: bi->sql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU; if ( c->value_int ) bi->sql_flags |= BSQLF_HAS_LDAPINFO_DN_RU; else bi->sql_flags &= ~BSQLF_HAS_LDAPINFO_DN_RU; break; case BSQL_FAIL_IF_NO_MAPPING: if ( c->value_int ) bi->sql_flags |= BSQLF_FAIL_IF_NO_MAPPING; else bi->sql_flags &= ~BSQLF_FAIL_IF_NO_MAPPING; break; case BSQL_ALLOW_ORPHANS: if ( c->value_int ) bi->sql_flags |= BSQLF_ALLOW_ORPHANS; else bi->sql_flags &= ~BSQLF_ALLOW_ORPHANS; break; case BSQL_SUBTREE_SHORTCUT: if ( c->value_int ) bi->sql_flags |= BSQLF_USE_SUBTREE_SHORTCUT; else bi->sql_flags &= ~BSQLF_USE_SUBTREE_SHORTCUT; break; case BSQL_FETCH_ALL_ATTRS: if ( c->value_int ) bi->sql_flags |= BSQLF_FETCH_ALL_ATTRS; else bi->sql_flags &= ~BSQLF_FETCH_ALL_ATTRS; break; case BSQL_CHECK_SCHEMA: if ( c->value_int ) bi->sql_flags |= BSQLF_CHECK_SCHEMA; else bi->sql_flags &= ~BSQLF_CHECK_SCHEMA; break; case BSQL_AUTOCOMMIT: if ( c->value_int ) bi->sql_flags |= BSQLF_AUTOCOMMIT_ON; else bi->sql_flags &= ~BSQLF_AUTOCOMMIT_ON; break; case BSQL_BASE_OBJECT: if ( c->be->be_nsuffix == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: suffix must be set", c->log ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); rc = ARG_BAD_CONF; break; } if ( bi->sql_baseObject ) { Debug( LDAP_DEBUG_CONFIG, "%s: " "\"baseObject\" already provided (will be overwritten)\n", c->log, 0, 0 ); entry_free( bi->sql_baseObject ); } if ( c->argc == 2 && !strcmp( c->argv[1], "TRUE" )) c->argc = 1; switch( c->argc ) { case 1: return create_baseObject( c->be, c->fname, c->lineno ); case 2: rc = read_baseObject( c->be, c->argv[ 1 ] ); if ( rc == 0 ) { ch_free( bi->sql_base_ob_file ); bi->sql_base_ob_file = c->value_string; } return rc; default: snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: trailing values in directive", c->log ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return 1; } break; case BSQL_LAYER: if ( backsql_api_config( bi, c->argv[ 1 ], c->argc - 2, &c->argv[ 2 ] ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: unable to load sql layer", c->log ); Debug( LDAP_DEBUG_ANY, "%s \"%s\"\n", c->cr_msg, c->argv[1], 0 ); return 1; } break; case BSQL_ALIASING_KEYWORD: if ( ! BER_BVISNULL( &bi->sql_aliasing ) ) { ch_free( bi->sql_aliasing.bv_val ); } ber_str2bv( c->argv[ 1 ], strlen( c->argv[ 1 ] ) + 1, 1, &bi->sql_aliasing ); /* add a trailing space... */ bi->sql_aliasing.bv_val[ bi->sql_aliasing.bv_len - 1] = ' '; break; case BSQL_FETCH_ATTRS: { char *str, *s, *next; const char *delimstr = ","; str = ch_strdup( c->argv[ 1 ] ); for ( s = ldap_pvt_strtok( str, delimstr, &next ); s != NULL; s = ldap_pvt_strtok( NULL, delimstr, &next ) ) { if ( strlen( s ) == 1 ) { if ( *s == '*' ) { bi->sql_flags |= BSQLF_FETCH_ALL_USERATTRS; c->argv[ 1 ][ s - str ] = ','; } else if ( *s == '+' ) { bi->sql_flags |= BSQLF_FETCH_ALL_OPATTRS; c->argv[ 1 ][ s - str ] = ','; } } } ch_free( str ); bi->sql_anlist = str2anlist( bi->sql_anlist, c->argv[ 1 ], delimstr ); if ( bi->sql_anlist == NULL ) { return -1; } } break; } return rc; }
int do_modify( Operation *op, SlapReply *rs ) { struct berval dn = BER_BVNULL; char textbuf[ SLAP_TEXT_BUFLEN ]; size_t textlen = sizeof( textbuf ); #ifdef LDAP_DEBUG Modifications *tmp; #endif Debug( LDAP_DEBUG_TRACE, "%s do_modify\n", op->o_log_prefix, 0, 0 ); /* * Parse the modify request. It looks like this: * * ModifyRequest := [APPLICATION 6] SEQUENCE { * name DistinguishedName, * mods SEQUENCE OF SEQUENCE { * operation ENUMERATED { * add (0), * delete (1), * replace (2) * }, * modification SEQUENCE { * type AttributeType, * values SET OF AttributeValue * } * } * } */ if ( ber_scanf( op->o_ber, "{m" /*}*/, &dn ) == LBER_ERROR ) { Debug( LDAP_DEBUG_ANY, "%s do_modify: ber_scanf failed\n", op->o_log_prefix, 0, 0 ); send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" ); return SLAPD_DISCONNECT; } Debug( LDAP_DEBUG_ARGS, "%s do_modify: dn (%s)\n", op->o_log_prefix, dn.bv_val, 0 ); rs->sr_err = slap_parse_modlist( op, rs, op->o_ber, &op->oq_modify ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s do_modify: slap_parse_modlist failed err=%d msg=%s\n", op->o_log_prefix, rs->sr_err, rs->sr_text ); send_ldap_result( op, rs ); goto cleanup; } if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s do_modify: get_ctrls failed\n", op->o_log_prefix, 0, 0 ); /* get_ctrls has sent results. Now clean up. */ goto cleanup; } rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); if( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s do_modify: invalid dn (%s)\n", op->o_log_prefix, dn.bv_val, 0 ); send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" ); goto cleanup; } op->orm_no_opattrs = 0; #ifdef LDAP_DEBUG Debug( LDAP_DEBUG_ARGS, "%s modifications:\n", op->o_log_prefix, 0, 0 ); for ( tmp = op->orm_modlist; tmp != NULL; tmp = tmp->sml_next ) { Debug( LDAP_DEBUG_ARGS, "\t%s: %s\n", tmp->sml_op == LDAP_MOD_ADD ? "add" : (tmp->sml_op == LDAP_MOD_INCREMENT ? "increment" : (tmp->sml_op == LDAP_MOD_DELETE ? "delete" : "replace")), tmp->sml_type.bv_val, 0 ); if ( tmp->sml_values == NULL ) { Debug( LDAP_DEBUG_ARGS, "%s\n", "\t\tno values", NULL, NULL ); } else if ( BER_BVISNULL( &tmp->sml_values[ 0 ] ) ) { Debug( LDAP_DEBUG_ARGS, "%s\n", "\t\tzero values", NULL, NULL ); } else if ( BER_BVISNULL( &tmp->sml_values[ 1 ] ) ) { Debug( LDAP_DEBUG_ARGS, "%s, length %ld\n", "\t\tone value", (long) tmp->sml_values[0].bv_len, NULL ); } else { Debug( LDAP_DEBUG_ARGS, "%s\n", "\t\tmultiple values", NULL, NULL ); } } if ( StatslogTest( LDAP_DEBUG_STATS ) ) { char abuf[BUFSIZ/2], *ptr = abuf; int len = 0; Statslog( LDAP_DEBUG_STATS, "%s MOD dn=\"%s\"\n", op->o_log_prefix, op->o_req_dn.bv_val, 0, 0, 0 ); for ( tmp = op->orm_modlist; tmp != NULL; tmp = tmp->sml_next ) { if (len + 1 + tmp->sml_type.bv_len > sizeof(abuf)) { Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n", op->o_log_prefix, abuf, 0, 0, 0 ); len = 0; ptr = abuf; if( 1 + tmp->sml_type.bv_len > sizeof(abuf)) { Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n", op->o_log_prefix, tmp->sml_type.bv_val, 0, 0, 0 ); continue; } } if (len) { *ptr++ = ' '; len++; } ptr = lutil_strcopy(ptr, tmp->sml_type.bv_val); len += tmp->sml_type.bv_len; } if (len) { Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n", op->o_log_prefix, abuf, 0, 0, 0 ); } } #endif /* LDAP_DEBUG */ rs->sr_err = slap_mods_check( op, op->orm_modlist, &rs->sr_text, textbuf, textlen, NULL ); if ( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); goto cleanup; } op->o_bd = frontendDB; rs->sr_err = frontendDB->be_modify( op, rs ); #ifdef LDAP_X_TXN if( rs->sr_err == LDAP_X_TXN_SPECIFY_OKAY ) { /* skip cleanup */ return rs->sr_err; } #endif cleanup: op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); if ( op->orm_modlist != NULL ) slap_mods_free( op->orm_modlist, 1 ); return rs->sr_err; }
static int rc_cf_gen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; retcode_t *rd = (retcode_t *)on->on_bi.bi_private; int rc = ARG_BAD_CONF; if ( c->op == SLAP_CONFIG_EMIT ) { switch( c->type ) { case RC_PARENT: if ( !BER_BVISEMPTY( &rd->rd_pdn )) { rc = value_add_one( &c->rvalue_vals, &rd->rd_pdn ); if ( rc == 0 ) { rc = value_add_one( &c->rvalue_nvals, &rd->rd_npdn ); } return rc; } rc = 0; break; case RC_ITEM: { retcode_item_t *rdi; int i; for ( rdi = rd->rd_item, i = 0; rdi; rdi = rdi->rdi_next, i++ ) { char buf[4096]; struct berval bv; char *ptr; bv.bv_len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i ); bv.bv_len += rdi->rdi_line.bv_len; ptr = bv.bv_val = ch_malloc( bv.bv_len + 1 ); ptr = lutil_strcopy( ptr, buf ); ptr = lutil_strncopy( ptr, rdi->rdi_line.bv_val, rdi->rdi_line.bv_len ); ber_bvarray_add( &c->rvalue_vals, &bv ); } rc = 0; } break; default: LDAP_BUG(); break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { switch( c->type ) { case RC_PARENT: if ( rd->rd_pdn.bv_val ) { ber_memfree ( rd->rd_pdn.bv_val ); rc = 0; } if ( rd->rd_npdn.bv_val ) { ber_memfree ( rd->rd_npdn.bv_val ); } break; case RC_ITEM: if ( c->valx == -1 ) { retcode_item_t *rdi, *next; for ( rdi = rd->rd_item; rdi != NULL; rdi = next ) { next = rdi->rdi_next; retcode_item_destroy( rdi ); } } else { retcode_item_t **rdip, *rdi; int i; for ( rdip = &rd->rd_item, i = 0; i <= c->valx && *rdip; i++, rdip = &(*rdip)->rdi_next ) ; if ( *rdip == NULL ) { return 1; } rdi = *rdip; *rdip = rdi->rdi_next; retcode_item_destroy( rdi ); } rc = 0; break; default: LDAP_BUG(); break; } return rc; /* FIXME */ } switch( c->type ) { case RC_PARENT: if ( rd->rd_pdn.bv_val ) { ber_memfree ( rd->rd_pdn.bv_val ); } if ( rd->rd_npdn.bv_val ) { ber_memfree ( rd->rd_npdn.bv_val ); } rd->rd_pdn = c->value_dn; rd->rd_npdn = c->value_ndn; rc = 0; break; case RC_ITEM: { retcode_item_t rdi = { BER_BVNULL }, **rdip; struct berval bv, rdn, nrdn; char *next = NULL; int i; if ( c->argc < 3 ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"retcode-item <RDN> <retcode> [<text>]\": " "missing args" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_str2bv( c->argv[ 1 ], 0, 0, &bv ); rc = dnPrettyNormal( NULL, &bv, &rdn, &nrdn, NULL ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to normalize RDN \"%s\": %d", c->argv[ 1 ], rc ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( !dnIsOneLevelRDN( &nrdn ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "value \"%s\" is not a RDN", c->argv[ 1 ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( BER_BVISNULL( &rd->rd_npdn ) ) { /* FIXME: we use the database suffix */ if ( c->be->be_nsuffix == NULL ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "either \"retcode-parent\" " "or \"suffix\" must be defined" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_dupbv( &rd->rd_pdn, &c->be->be_suffix[ 0 ] ); ber_dupbv( &rd->rd_npdn, &c->be->be_nsuffix[ 0 ] ); } build_new_dn( &rdi.rdi_dn, &rd->rd_pdn, &rdn, NULL ); build_new_dn( &rdi.rdi_ndn, &rd->rd_npdn, &nrdn, NULL ); ch_free( rdn.bv_val ); ch_free( nrdn.bv_val ); rdi.rdi_err = strtol( c->argv[ 2 ], &next, 0 ); if ( next == c->argv[ 2 ] || next[ 0 ] != '\0' ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to parse return code \"%s\"", c->argv[ 2 ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } rdi.rdi_mask = SN_DG_OP_ALL; if ( c->argc > 3 ) { for ( i = 3; i < c->argc; i++ ) { if ( strncasecmp( c->argv[ i ], "op=", STRLENOF( "op=" ) ) == 0 ) { char **ops; int j; ops = ldap_str2charray( &c->argv[ i ][ STRLENOF( "op=" ) ], "," ); assert( ops != NULL ); rdi.rdi_mask = SN_DG_OP_NONE; for ( j = 0; ops[ j ] != NULL; j++ ) { if ( strcasecmp( ops[ j ], "add" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_ADD; } else if ( strcasecmp( ops[ j ], "bind" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_BIND; } else if ( strcasecmp( ops[ j ], "compare" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_COMPARE; } else if ( strcasecmp( ops[ j ], "delete" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_DELETE; } else if ( strcasecmp( ops[ j ], "modify" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_MODIFY; } else if ( strcasecmp( ops[ j ], "rename" ) == 0 || strcasecmp( ops[ j ], "modrdn" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_RENAME; } else if ( strcasecmp( ops[ j ], "search" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_SEARCH; } else if ( strcasecmp( ops[ j ], "extended" ) == 0 ) { rdi.rdi_mask |= SN_DG_EXTENDED; } else if ( strcasecmp( ops[ j ], "auth" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_AUTH; } else if ( strcasecmp( ops[ j ], "read" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_READ; } else if ( strcasecmp( ops[ j ], "write" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_WRITE; } else if ( strcasecmp( ops[ j ], "all" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_ALL; } else { snprintf( c->cr_msg, sizeof(c->cr_msg), "unknown op \"%s\"", ops[ j ] ); ldap_charray_free( ops ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } ldap_charray_free( ops ); } else if ( strncasecmp( c->argv[ i ], "text=", STRLENOF( "text=" ) ) == 0 ) { if ( !BER_BVISNULL( &rdi.rdi_text ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"text\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_str2bv( &c->argv[ i ][ STRLENOF( "text=" ) ], 0, 1, &rdi.rdi_text ); } else if ( strncasecmp( c->argv[ i ], "matched=", STRLENOF( "matched=" ) ) == 0 ) { struct berval dn; if ( !BER_BVISNULL( &rdi.rdi_matched ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"matched\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_str2bv( &c->argv[ i ][ STRLENOF( "matched=" ) ], 0, 0, &dn ); if ( dnPretty( NULL, &dn, &rdi.rdi_matched, NULL ) != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to prettify matched DN \"%s\"", &c->argv[ i ][ STRLENOF( "matched=" ) ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } else if ( strncasecmp( c->argv[ i ], "ref=", STRLENOF( "ref=" ) ) == 0 ) { char **refs; int j; if ( rdi.rdi_ref != NULL ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"ref\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( rdi.rdi_err != LDAP_REFERRAL ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "providing \"ref\" " "along with a non-referral " "resultCode may cause slapd failures " "related to internal checks" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); } refs = ldap_str2charray( &c->argv[ i ][ STRLENOF( "ref=" ) ], " " ); assert( refs != NULL ); for ( j = 0; refs[ j ] != NULL; j++ ) { struct berval bv; ber_str2bv( refs[ j ], 0, 1, &bv ); ber_bvarray_add( &rdi.rdi_ref, &bv ); } ldap_charray_free( refs ); } else if ( strncasecmp( c->argv[ i ], "sleeptime=", STRLENOF( "sleeptime=" ) ) == 0 ) { if ( rdi.rdi_sleeptime != 0 ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"sleeptime\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( lutil_atoi( &rdi.rdi_sleeptime, &c->argv[ i ][ STRLENOF( "sleeptime=" ) ] ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to parse \"sleeptime=%s\"", &c->argv[ i ][ STRLENOF( "sleeptime=" ) ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } else if ( strncasecmp( c->argv[ i ], "unsolicited=", STRLENOF( "unsolicited=" ) ) == 0 ) { char *data; if ( !BER_BVISNULL( &rdi.rdi_unsolicited_oid ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"unsolicited\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } data = strchr( &c->argv[ i ][ STRLENOF( "unsolicited=" ) ], ':' ); if ( data != NULL ) { struct berval oid; if ( ldif_parse_line2( &c->argv[ i ][ STRLENOF( "unsolicited=" ) ], &oid, &rdi.rdi_unsolicited_data, NULL ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to parse \"unsolicited\"" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_dupbv( &rdi.rdi_unsolicited_oid, &oid ); } else { ber_str2bv( &c->argv[ i ][ STRLENOF( "unsolicited=" ) ], 0, 1, &rdi.rdi_unsolicited_oid ); } } else if ( strncasecmp( c->argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 ) { char *arg = &c->argv[ i ][ STRLENOF( "flags=" ) ]; if ( strcasecmp( arg, "disconnect" ) == 0 ) { rdi.rdi_flags |= RDI_PRE_DISCONNECT; } else if ( strcasecmp( arg, "pre-disconnect" ) == 0 ) { rdi.rdi_flags |= RDI_PRE_DISCONNECT; } else if ( strcasecmp( arg, "post-disconnect" ) == 0 ) { rdi.rdi_flags |= RDI_POST_DISCONNECT; } else { snprintf( c->cr_msg, sizeof(c->cr_msg), "unknown flag \"%s\"", arg ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } else { snprintf( c->cr_msg, sizeof(c->cr_msg), "unknown option \"%s\"", c->argv[ i ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } } rdi.rdi_line.bv_len = 2*(c->argc - 1) + c->argc - 2; for ( i = 1; i < c->argc; i++ ) { rdi.rdi_line.bv_len += strlen( c->argv[ i ] ); } next = rdi.rdi_line.bv_val = ch_malloc( rdi.rdi_line.bv_len + 1 ); for ( i = 1; i < c->argc; i++ ) { *next++ = '"'; next = lutil_strcopy( next, c->argv[ i ] ); *next++ = '"'; *next++ = ' '; } *--next = '\0'; for ( rdip = &rd->rd_item; *rdip; rdip = &(*rdip)->rdi_next ) /* go to last */ ; *rdip = ( retcode_item_t * )ch_malloc( sizeof( retcode_item_t ) ); *(*rdip) = rdi; rc = 0; } break; default: rc = SLAP_CONF_UNKNOWN; break; } return rc; }
static int dgroup_cf( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; int rc = 1; switch( c->op ) { case SLAP_CONFIG_EMIT: { adpair *ap; for ( ap = on->on_bi.bi_private; ap; ap = ap->ap_next ) { struct berval bv; char *ptr; bv.bv_len = ap->ap_mem->ad_cname.bv_len + 1 + ap->ap_uri->ad_cname.bv_len; bv.bv_val = ch_malloc( bv.bv_len + 1 ); ptr = lutil_strcopy( bv.bv_val, ap->ap_mem->ad_cname.bv_val ); *ptr++ = ' '; strcpy( ptr, ap->ap_uri->ad_cname.bv_val ); ber_bvarray_add( &c->rvalue_vals, &bv ); rc = 0; } } break; case LDAP_MOD_DELETE: if ( c->valx == -1 ) { adpair *ap; while (( ap = on->on_bi.bi_private )) { on->on_bi.bi_private = ap->ap_next; ch_free( ap ); } } else { adpair **app, *ap; int i; app = (adpair **)&on->on_bi.bi_private; for (i=0; i<=c->valx; i++, app = &ap->ap_next) { ap = *app; } *app = ap->ap_next; ch_free( ap ); } rc = 0; break; case SLAP_CONFIG_ADD: case LDAP_MOD_ADD: { adpair ap = { NULL, NULL, NULL }, *a2; const char *text; if ( slap_str2ad( c->argv[1], &ap.ap_mem, &text ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s attribute description unknown: \"%s\"", c->argv[0], c->argv[1] ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg, 0 ); return ARG_BAD_CONF; } if ( slap_str2ad( c->argv[2], &ap.ap_uri, &text ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s attribute description unknown: \"%s\"", c->argv[0], c->argv[2] ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg, 0 ); return ARG_BAD_CONF; } /* The on->on_bi.bi_private pointer can be used for * anything this instance of the overlay needs. */ a2 = ch_malloc( sizeof(adpair) ); a2->ap_next = on->on_bi.bi_private; a2->ap_mem = ap.ap_mem; a2->ap_uri = ap.ap_uri; on->on_bi.bi_private = a2; rc = 0; } } return rc; }
/* return 0 IFF op_dn is a value in group_at (member) attribute * of entry with gr_dn AND that entry has an objectClass * value of group_oc (groupOfNames) */ int ldap_back_group( Backend *be, Connection *conn, Operation *op, Entry *target, struct berval *gr_ndn, struct berval *op_ndn, ObjectClass *group_oc, AttributeDescription* group_at ) { struct ldapinfo *li = (struct ldapinfo *) be->be_private; int rc = 1; Attribute *attr; LDAPMessage *result; char *gattr[2]; char *filter = NULL, *ptr; LDAP *ld; struct berval mop_ndn = { 0, NULL }, mgr_ndn = { 0, NULL }; AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass; struct berval group_oc_name = {0, NULL}; struct berval group_at_name = group_at->ad_cname; if( group_oc->soc_names && group_oc->soc_names[0] ) { group_oc_name.bv_val = group_oc->soc_names[0]; } else { group_oc_name.bv_val = group_oc->soc_oid; } if (group_oc_name.bv_val) group_oc_name.bv_len = strlen(group_oc_name.bv_val); if (target != NULL && dn_match( &target->e_nname, gr_ndn ) ) { /* we already have a copy of the entry */ /* attribute and objectclass mapping has already been done */ /* * first we need to check if the objectClass attribute * has been retieved; otherwise we need to repeat the search */ attr = attr_find( target->e_attrs, ad_objectClass ); if ( attr != NULL ) { /* * Now we can check for the group objectClass value */ if( !is_entry_objectclass( target, group_oc, 0 ) ) { return(1); } /* * This part has been reworked: the group attr compare * fails only if the attribute is PRESENT but the value * is NOT PRESENT; if the attribute is NOT PRESENT, the * search must be repeated as well. * This may happen if a search for an entry has already * been performed (target is not null) but the group * attribute has not been required */ if ((attr = attr_find(target->e_attrs, group_at)) != NULL) { if( value_find_ex( group_at, SLAP_MR_VALUE_NORMALIZED_MATCH, attr->a_vals, op_ndn ) != LDAP_SUCCESS ) return(1); return(0); } /* else: repeat the search */ } /* else: repeat the search */ } /* else: do the search */ /* * Rewrite the op ndn if needed */ #ifdef ENABLE_REWRITE switch ( rewrite_session( li->rwinfo, "bindDn", op_ndn->bv_val, conn, &mop_ndn.bv_val ) ) { case REWRITE_REGEXEC_OK: if ( mop_ndn.bv_val == NULL ) { mop_ndn = *op_ndn; } #ifdef NEW_LOGGING LDAP_LOG( BACK_LDAP, DETAIL1, "[rw] bindDn (op ndn in group): \"%s\" -> \"%s\"\n", op_ndn->bv_val, mop_ndn.bv_val, 0 ); #else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ARGS, "rw> bindDn (op ndn in group): \"%s\" -> \"%s\"\n%s", op_ndn->bv_val, mop_ndn.bv_val, "" ); #endif /* !NEW_LOGGING */ break; case REWRITE_REGEXEC_UNWILLING: case REWRITE_REGEXEC_ERR: goto cleanup; } /* * Rewrite the gr ndn if needed */ switch ( rewrite_session( li->rwinfo, "searchBase", gr_ndn->bv_val, conn, &mgr_ndn.bv_val ) ) { case REWRITE_REGEXEC_OK: if ( mgr_ndn.bv_val == NULL ) { mgr_ndn = *gr_ndn; } #ifdef NEW_LOGGING LDAP_LOG( BACK_LDAP, DETAIL1, "[rw] searchBase (gr ndn in group): \"%s\" -> \"%s\"\n%s", gr_ndn->bv_val, mgr_ndn.bv_val, "" ); #else /* !NEW_LOGGING */ Debug( LDAP_DEBUG_ARGS, "rw> searchBase (gr ndn in group):" " \"%s\" -> \"%s\"\n%s", gr_ndn->bv_val, mgr_ndn.bv_val, "" ); #endif /* !NEW_LOGGING */ break; case REWRITE_REGEXEC_UNWILLING: case REWRITE_REGEXEC_ERR: goto cleanup; } #else /* !ENABLE_REWRITE */ ldap_back_dn_massage( li, op_ndn, &mop_ndn, 1, 1 ); if ( mop_ndn.bv_val == NULL ) { goto cleanup; } ldap_back_dn_massage( li, gr_ndn, &mgr_ndn, 1, 1 ); if ( mgr_ndn.bv_val == NULL ) { goto cleanup; } #endif /* !ENABLE_REWRITE */ ldap_back_map(&li->oc_map, &group_oc_name, &group_oc_name, BACKLDAP_MAP); if (group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0') goto cleanup; ldap_back_map(&li->at_map, &group_at_name, &group_at_name, BACKLDAP_MAP); if (group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0') goto cleanup; filter = ch_malloc(sizeof("(&(objectclass=)(=))") + group_oc_name.bv_len + group_at_name.bv_len + mop_ndn.bv_len + 1); if (filter == NULL) goto cleanup; if (ldap_initialize(&ld, li->url) != LDAP_SUCCESS) { goto cleanup; } if (ldap_bind_s(ld, li->binddn, li->bindpw, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) { goto cleanup; } ptr = lutil_strcopy(filter, "(&(objectclass="); ptr = lutil_strcopy(ptr, group_oc_name.bv_val); ptr = lutil_strcopy(ptr, ")("); ptr = lutil_strcopy(ptr, group_at_name.bv_val); ptr = lutil_strcopy(ptr, "="); ptr = lutil_strcopy(ptr, mop_ndn.bv_val); strcpy(ptr, "))"); gattr[0] = "objectclass"; gattr[1] = NULL; if (ldap_search_ext_s(ld, mgr_ndn.bv_val, LDAP_SCOPE_BASE, filter, gattr, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result) == LDAP_SUCCESS) { if (ldap_first_entry(ld, result) != NULL) rc = 0; ldap_msgfree(result); } cleanup:; if ( ld != NULL ) { ldap_unbind(ld); } ch_free(filter); if ( mop_ndn.bv_val != op_ndn->bv_val ) { free( mop_ndn.bv_val ); } if ( mgr_ndn.bv_val != gr_ndn->bv_val ) { free( mgr_ndn.bv_val ); } return(rc); }