static int pack_vlv_response_control( Operation *op, SlapReply *rs, sort_op *so, LDAPControl **ctrlsp ) { LDAPControl *ctrl; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; struct berval cookie, bv; int rc; ber_init2( ber, NULL, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); rc = ber_printf( ber, "{iie", so->so_vlv_target, so->so_nentries, so->so_vlv_rc ); if ( rc != -1 && so->so_vcontext ) { cookie.bv_val = (char *)&so->so_vcontext; cookie.bv_len = sizeof(so->so_vcontext); rc = ber_printf( ber, "tO", LDAP_VLVCONTEXT_IDENTIFIER, &cookie ); } if ( rc != -1 ) { rc = ber_printf( ber, "}" ); } if ( rc != -1 ) { rc = ber_flatten2( ber, &bv, 0 ); } if ( rc != -1 ) { ctrl = (LDAPControl *)op->o_tmpalloc( sizeof(LDAPControl)+ bv.bv_len, op->o_tmpmemctx ); ctrl->ldctl_oid = LDAP_CONTROL_VLVRESPONSE; ctrl->ldctl_iscritical = 0; ctrl->ldctl_value.bv_val = (char *)(ctrl+1); ctrl->ldctl_value.bv_len = bv.bv_len; AC_MEMCPY( ctrl->ldctl_value.bv_val, bv.bv_val, bv.bv_len ); ctrlsp[0] = ctrl; } else { ctrlsp[0] = NULL; rs->sr_err = LDAP_OTHER; } ber_free_buf( ber ); return rs->sr_err; }
static char *cpy_addresses( char ***tgtio, char *buf, char **src, int len ) { char **tgt=*tgtio; for( ; (*src) ; src++ ) { AC_MEMCPY( buf, *src, len ); *tgt++=buf; buf+=len; } *tgtio=tgt; return buf; }
/* Append sorted list b to sorted list a. The result is unsorted but * a[1] is the min of the result and a[a[0]] is the max. */ int bdb_idl_append( ID *a, ID *b ) { ID ida, idb, tmp, swap = 0; if ( BDB_IDL_IS_ZERO( b ) ) { return 0; } if ( BDB_IDL_IS_ZERO( a ) ) { BDB_IDL_CPY( a, b ); return 0; } ida = BDB_IDL_LAST( a ); idb = BDB_IDL_LAST( b ); if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) || a[0] + b[0] >= BDB_IDL_UM_MAX ) { a[2] = IDL_MAX( ida, idb ); a[1] = IDL_MIN( a[1], b[1] ); a[0] = NOID; return 0; } if ( b[0] > 1 && ida > idb ) { swap = idb; a[a[0]] = idb; b[b[0]] = ida; } if ( b[1] < a[1] ) { tmp = a[1]; a[1] = b[1]; } else { tmp = b[1]; } a[0]++; a[a[0]] = tmp; if ( b[0] > 1 ) { int i = b[0] - 1; AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID)); a[0] += i; } if ( swap ) { b[b[0]] = swap; } return 0; }
static char *cpy_aliases( char ***tgtio, char *buf, char **src ) { int len; char **tgt=*tgtio; for( ; (*src) ; src++ ) { len = strlen( *src ) + 1; AC_MEMCPY( buf, *src, len ); *tgt++=buf; buf+=len; } *tgtio=tgt; return buf; }
int rewrite_var_replace( struct rewrite_var *var, const char *value, int flags ) { ber_len_t len; assert( value != NULL ); len = strlen( value ); if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) { if ( flags & REWRITE_VAR_COPY_VALUE ) { if ( len <= var->lv_value.bv_len ) { AC_MEMCPY(var->lv_value.bv_val, value, len + 1); } else { free( var->lv_value.bv_val ); var->lv_value.bv_val = strdup( value ); } } else { free( var->lv_value.bv_val ); var->lv_value.bv_val = (char *)value; var->lv_flags &= ~REWRITE_VAR_COPY_VALUE; } } else { if ( flags & REWRITE_VAR_COPY_VALUE ) { var->lv_value.bv_val = strdup( value ); var->lv_flags |= REWRITE_VAR_COPY_VALUE; } else { var->lv_value.bv_val = (char *)value; } } if ( var->lv_value.bv_val == NULL ) { return -1; } var->lv_value.bv_len = len; return 0; }
static int dupent_response_done( Operation *op, SlapReply *rs ) { BerElementBuffer berbuf; BerElement *ber = (BerElement *) &berbuf; struct berval ctrlval; LDAPControl *ctrl, *ctrlsp[2]; ber_init2( ber, NULL, LBER_USE_DER ); /* DuplicateEntryResponseDone ::= SEQUENCE { resultCode, -- From [RFC2251] errorMessage [0] LDAPString OPTIONAL, attribute [1] AttributeDescription OPTIONAL } */ ber_printf( ber, "{i}", rs->sr_err ); if ( ber_flatten2( ber, &ctrlval, 0 ) == -1 ) { ber_free_buf( ber ); if ( op->o_dupent == SLAP_CONTROL_CRITICAL ) { return LDAP_CONSTRAINT_VIOLATION; } return SLAP_CB_CONTINUE; } ctrl = op->o_tmpcalloc( 1, sizeof( LDAPControl ) + ctrlval.bv_len + 1, op->o_tmpmemctx ); ctrl->ldctl_value.bv_val = (char *)&ctrl[ 1 ]; ctrl->ldctl_oid = LDAP_CONTROL_DUPENT_RESPONSE; ctrl->ldctl_iscritical = 0; ctrl->ldctl_value.bv_len = ctrlval.bv_len; AC_MEMCPY( ctrl->ldctl_value.bv_val, ctrlval.bv_val, ctrlval.bv_len ); ctrl->ldctl_value.bv_val[ ctrl->ldctl_value.bv_len ] = '\0'; ber_free_buf( ber ); ctrlsp[0] = ctrl; ctrlsp[1] = NULL; slap_add_ctrls( op, rs, ctrlsp ); return SLAP_CB_CONTINUE; }
static void add_lower(ac_uint4 code) { ac_uint4 i, j; /* * Always map the code to itself. */ cases[1] = code; /* * If the title case character is empty, then make it the same as the * upper case. */ if (cases[2] == 0) cases[2] = cases[0]; if (lower_used == lower_size) { if (lower_size == 0) lower = (_case_t *) malloc(sizeof(_case_t) << 3); else lower = (_case_t *) realloc((char *) lower, sizeof(_case_t) * (lower_size + 8)); lower_size += 8; } /* * Locate the insertion point. */ for (i = 0; i < lower_used && code > lower[i].key; i++) ; if (i < lower_used) { /* * Shift the array up by one. */ for (j = lower_used; j > i; j--) (void) AC_MEMCPY((char *) &lower[j], (char *) &lower[j - 1], sizeof(_case_t)); } lower[i].key = cases[1]; /* Lower */ lower[i].other1 = cases[0]; /* Upper */ lower[i].other2 = cases[2]; /* Title */ lower_used++; }
int bdb_dn2id_children( Operation *op, DB_TXN *txn, Entry *e ) { DBT key, data; struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; DB *db = bdb->bi_dn2id->bdi_db; ID id; int rc; Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_children(\"%s\")\n", e->e_nname.bv_val, 0, 0 ); DBTzero( &key ); key.size = e->e_nname.bv_len + 2; key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx ); ((char *)key.data)[0] = DN_ONE_PREFIX; AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 ); if ( bdb->bi_idl_cache_size ) { rc = bdb_idl_cache_get( bdb, db, &key, NULL ); if ( rc != LDAP_NO_SUCH_OBJECT ) { op->o_tmpfree( key.data, op->o_tmpmemctx ); return rc; } } /* we actually could do a empty get... */ DBTzero( &data ); data.data = &id; data.ulen = sizeof(id); data.flags = DB_DBT_USERMEM; data.doff = 0; data.dlen = sizeof(id); rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags ); op->o_tmpfree( key.data, op->o_tmpmemctx ); Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children(\"%s\"): %s (%d)\n", e->e_nname.bv_val, rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " : db_strerror(rc) ), rc ); return rc; }
int ldap_get_entry_controls( LDAP *ld, LDAPMessage *entry, LDAPControl ***sctrls ) { int rc; BerElement be; assert( ld != NULL ); assert( LDAP_VALID( ld ) ); assert( entry != NULL ); assert( sctrls != NULL ); if ( entry->lm_msgtype != LDAP_RES_SEARCH_ENTRY ) { return LDAP_PARAM_ERROR; } /* make a local copy of the BerElement */ AC_MEMCPY(&be, entry->lm_ber, sizeof(be)); if ( ber_scanf( &be, "{xx" /*}*/ ) == LBER_ERROR ) { rc = LDAP_DECODING_ERROR; goto cleanup_and_return; } rc = ldap_pvt_get_controls( &be, sctrls ); cleanup_and_return: if( rc != LDAP_SUCCESS ) { ld->ld_errno = rc; if( ld->ld_matched != NULL ) { LDAP_FREE( ld->ld_matched ); ld->ld_matched = NULL; } if( ld->ld_error != NULL ) { LDAP_FREE( ld->ld_error ); ld->ld_error = NULL; } } return rc; }
int bdb_dn2id( Operation *op, struct berval *dn, EntryInfo *ei, DB_TXN *txn, DBC **cursor ) { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; DB *db = bdb->bi_dn2id->bdi_db; int rc; DBT key, data; ID nid; Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id(\"%s\")\n", dn->bv_val, 0, 0 ); DBTzero( &key ); key.size = dn->bv_len + 2; key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx ); ((char *)key.data)[0] = DN_BASE_PREFIX; AC_MEMCPY( &((char *)key.data)[1], dn->bv_val, key.size - 1 ); /* store the ID */ DBTzero( &data ); data.data = &nid; data.ulen = sizeof(ID); data.flags = DB_DBT_USERMEM; rc = db->cursor( db, txn, cursor, bdb->bi_db_opflags ); /* fetch it */ if ( !rc ) rc = (*cursor)->c_get( *cursor, &key, &data, DB_SET ); if( rc != 0 ) { Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: get failed: %s (%d)\n", db_strerror( rc ), rc, 0 ); } else { BDB_DISK2ID( &nid, &ei->bei_id ); Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: got id=0x%lx\n", ei->bei_id, 0, 0 ); } op->o_tmpfree( key.data, op->o_tmpmemctx ); return rc; }
static Datum ldbm_get_next( LDBM ldbm, kvpair (*fptr)(MDBM *, kvpair) ) { kvpair out; kvpair in; Datum ret; size_t sz = MDBM_PAGE_SIZE(ldbm); #ifdef NO_NULL_KEY int delta = 1; #else int delta = 0; #endif /* LDBM_RLOCK; */ in.key.dsize = sz; /* Assume first key in one pg */ in.key.dptr = malloc(sz); in.val.dptr = NULL; /* Don't need data just key */ in.val.dsize = 0; ret.dptr = NULL; ret.dsize = NULL; out = fptr( ldbm, in ); if (out.key.dsize > 0) { ret.dsize = out.key.dsize - delta; if ((ret.dptr = (char *)malloc(ret.dsize)) == NULL) { ret.dsize = 0; ret.dptr = NULL; } else { AC_MEMCPY(ret.dptr, (void *)(out.key.dptr + delta), ret.dsize ); } } /* LDBM_RUNLOCK; */ free(in.key.dptr); return ret; }
static char *v2ref( BerVarray ref, const char *text ) { size_t len = 0, i = 0; char *v2; if(ref == NULL) { if (text) { return ch_strdup(text); } else { return NULL; } } if ( text != NULL ) { len = strlen( text ); if (text[len-1] != '\n') { i = 1; } } v2 = ch_malloc( len+i+sizeof("Referral:") ); if( text != NULL ) { strcpy(v2, text); if( i ) { v2[len++] = '\n'; } } strcpy( v2+len, "Referral:" ); len += sizeof("Referral:"); for( i=0; ref[i].bv_val != NULL; i++ ) { v2 = ch_realloc( v2, len + ref[i].bv_len + 1 ); v2[len-1] = '\n'; AC_MEMCPY(&v2[len], ref[i].bv_val, ref[i].bv_len ); len += ref[i].bv_len; if (ref[i].bv_val[ref[i].bv_len-1] != '/') { ++len; } } v2[len-1] = '\0'; return v2; }
static int parse_paged_cookie( Operation *op, SlapReply *rs ) { int rc = LDAP_SUCCESS; PagedResultsState *ps = op->o_pagedresults_state; /* this function must be invoked only if the pagedResults * control has been detected, parsed and partially checked * by the frontend */ assert( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ); /* cookie decoding/checks deferred to backend... */ if ( ps->ps_cookieval.bv_len ) { PagedResultsCookie reqcookie; if( ps->ps_cookieval.bv_len != sizeof( reqcookie ) ) { /* bad cookie */ rs->sr_text = "paged results cookie is invalid"; rc = LDAP_PROTOCOL_ERROR; goto done; } AC_MEMCPY( &reqcookie, ps->ps_cookieval.bv_val, sizeof( reqcookie )); if ( reqcookie > ps->ps_cookie ) { /* bad cookie */ rs->sr_text = "paged results cookie is invalid"; rc = LDAP_PROTOCOL_ERROR; goto done; } else if ( reqcookie < ps->ps_cookie ) { rs->sr_text = "paged results cookie is invalid or old"; rc = LDAP_UNWILLING_TO_PERFORM; goto done; } } else { /* we're going to use ps_cookie */ op->o_conn->c_pagedresults_state.ps_cookie = 0; } done:; return rc; }
static int ainfo_insert( struct bdb_info *bdb, AttrInfo *a ) { int x; int i = bdb_attr_slot( bdb, a->ai_desc, &x ); /* Is it a dup? */ if ( i >= 0 ) return -1; bdb->bi_attrs = ch_realloc( bdb->bi_attrs, ( bdb->bi_nattrs+1 ) * sizeof( AttrInfo * )); if ( x < bdb->bi_nattrs ) AC_MEMCPY( &bdb->bi_attrs[x+1], &bdb->bi_attrs[x], ( bdb->bi_nattrs - x ) * sizeof( AttrInfo *)); bdb->bi_attrs[x] = a; bdb->bi_nattrs++; return 0; }
static int ainfo_insert( struct mdb_info *mdb, AttrInfo *a ) { int x; int i = mdb_attr_slot( mdb, a->ai_desc, &x ); /* Is it a dup? */ if ( i >= 0 ) return -1; mdb->mi_attrs = ch_realloc( mdb->mi_attrs, ( mdb->mi_nattrs+1 ) * sizeof( AttrInfo * )); if ( x < mdb->mi_nattrs ) AC_MEMCPY( &mdb->mi_attrs[x+1], &mdb->mi_attrs[x], ( mdb->mi_nattrs - x ) * sizeof( AttrInfo *)); mdb->mi_attrs[x] = a; mdb->mi_nattrs++; return 0; }
/* insert id */ AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) ); ids[x] = id; } #if IDL_DEBUG > 1 idl_dump( ids ); #elif IDL_DEBUG > 0 idl_check( ids ); #endif return 0; } #if 0 /* unused */ static int idl_delete( ID *ids, ID id ) { unsigned x = bdb_idl_search( ids, id ); #if IDL_DEBUG > 1 #ifdef NEW_LOGGING LDAP_LOG( INDEX, DETAIL1, "delete: %04lx at %d\n", (long) id, x, 0 ); #else Debug( LDAP_DEBUG_ANY, "delete: %04lx at %d\n", (long) id, x, 0 ); idl_dump( ids ); #endif #elif IDL_DEBUG > 0 idl_check( ids ); #endif assert( x > 0 ); if( x <= 0 ) { /* internal error */ return -2; } if( x > ids[0] || ids[x] != id ) { /* not found */ return -1; } else if ( --ids[0] == 0 ) { if( x != 1 ) { return -3; } } else { AC_MEMCPY( &ids[x], &ids[x+1], (1+ids[0]-x) * sizeof(ID) ); } #if IDL_DEBUG > 1 idl_dump( ids ); #elif IDL_DEBUG > 0 idl_check( ids ); #endif return 0; }
int ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) { int rc; Datum int_key; /* Internal key */ #ifdef MDBM_DEBUG fprintf( stdout, "==>(mdbm)ldbm_store(db=%p, key(dptr=%p,sz=%d), data(dptr=%p,sz=%d), flags=%x)\n", ldbm, key.dptr, key.dsize, data.dptr, data.dsize, flags ); fflush( stdout ); #endif /* LDBM_WLOCK; */ #ifdef NO_NULL_KEY int_key.dsize = key.dsize + 1; int_key.dptr = malloc( int_key.dsize ); *(int_key.dptr) = 'l'; /* Must not be NULL !*/ AC_MEMCPY( (void *)(int_key.dptr + 1), key.dptr, key.dsize ); #else int_key = key; #endif rc = mdbm_store( ldbm, int_key, data, flags ); if ( flags & LDBM_SYNC ) { mdbm_sync( ldbm ); } /* LDBM_WUNLOCK; */ #ifdef MDBM_DEBUG fprintf( stdout, "<==(mdbm)ldbm_store(rc=%d)\n", rc ); fflush( stdout ); #endif #ifdef NO_NULL_KEY free(int_key.dptr); #endif return( rc ); }
static int OpenLDAPaciNormalizeRights( struct berval *actions, struct berval *nactions, void *ctx ) { struct berval bv = BER_BVNULL; int i; BER_BVZERO( nactions ); for ( i = 0; acl_get_part( actions, i, '$', &bv ) >= 0; i++ ) { int rc; struct berval nbv; rc = OpenLDAPaciNormalizeRight( &bv, &nbv, ctx ); if ( rc != LDAP_SUCCESS ) { ber_memfree_x( nactions->bv_val, ctx ); BER_BVZERO( nactions ); return LDAP_INVALID_SYNTAX; } if ( i == 0 ) { *nactions = nbv; } else { nactions->bv_val = ber_memrealloc_x( nactions->bv_val, nactions->bv_len + STRLENOF( "$" ) + nbv.bv_len + 1, ctx ); nactions->bv_val[ nactions->bv_len ] = '$'; AC_MEMCPY( &nactions->bv_val[ nactions->bv_len + 1 ], nbv.bv_val, nbv.bv_len + 1 ); ber_memfree_x( nbv.bv_val, ctx ); nactions->bv_len += STRLENOF( "$" ) + nbv.bv_len; } BER_BVZERO( &nbv ); } return LDAP_SUCCESS; }
/* Drop a processed packet from the input buffer */ static void sb_sasl_generic_drop_packet ( struct sb_sasl_generic_data *p, int debuglevel ) { ber_slen_t len; len = p->sec_buf_in.buf_ptr - p->sec_buf_in.buf_end; if ( len > 0 ) AC_MEMCPY( p->sec_buf_in.buf_base, p->sec_buf_in.buf_base + p->sec_buf_in.buf_end, len ); if ( len >= 4 ) { p->sec_buf_in.buf_end = sb_sasl_generic_pkt_length(p, (unsigned char *) p->sec_buf_in.buf_base, debuglevel); } else { p->sec_buf_in.buf_end = 0; } p->sec_buf_in.buf_ptr = len; }
Datum ldbm_datum_dup( LDBM ldbm, Datum data ) { Datum dup; ldbm_datum_init( dup ); if ( data.dsize == 0 ) { dup.dsize = 0; dup.dptr = NULL; return( dup ); } dup.dsize = data.dsize; if ( (dup.dptr = (char *) malloc( data.dsize )) != NULL ) { AC_MEMCPY( dup.dptr, data.dptr, data.dsize ); } return( dup ); }
/* * Read from the ber buffer. The caller must maintain ber->ber_tag. * Do not use to read whole tags. See ber_get_tag() and ber_skip_data(). */ ber_slen_t ber_read( BerElement *ber, char *buf, ber_len_t len ) { ber_len_t actuallen, nleft; assert( ber != NULL ); assert( buf != NULL ); assert( LBER_VALID( ber ) ); nleft = ber_pvt_ber_remaining( ber ); actuallen = nleft < len ? nleft : len; AC_MEMCPY( buf, ber->ber_ptr, actuallen ); ber->ber_ptr += actuallen; return( (ber_slen_t) actuallen ); }
static void add_title(ac_uint4 code) { ac_uint4 i, j; /* * Always map the code to itself. */ cases[2] = code; if (title_used == title_size) { if (title_size == 0) title = (_case_t *) malloc(sizeof(_case_t) << 3); else title = (_case_t *) realloc((char *) title, sizeof(_case_t) * (title_size + 8)); title_size += 8; } /* * Locate the insertion point. */ for (i = 0; i < title_used && code > title[i].key; i++) ; if (i < title_used) { /* * Shift the array up by one. */ for (j = title_used; j > i; j--) (void) AC_MEMCPY((char *) &title[j], (char *) &title[j - 1], sizeof(_case_t)); } title[i].key = cases[2]; /* Title */ title[i].other1 = cases[0]; /* Upper */ title[i].other2 = cases[1]; /* Lower */ title_used++; }
char *ldap_pvt_ctime( const time_t *tp, char *buf ) { #ifdef USE_CTIME_R # if (CTIME_R_NARGS > 3) || (CTIME_R_NARGS < 2) # error "CTIME_R_NARGS should be 2 or 3" # elif CTIME_R_NARGS > 2 && defined(CTIME_R_RETURNS_INT) return( ctime_r(tp,buf,26) < 0 ? 0 : buf ); # elif CTIME_R_NARGS > 2 return ctime_r(tp,buf,26); # else return ctime_r(tp,buf); # endif #else LDAP_MUTEX_LOCK( &ldap_int_ctime_mutex ); AC_MEMCPY( buf, ctime(tp), 26 ); LDAP_MUTEX_UNLOCK( &ldap_int_ctime_mutex ); return buf; #endif }
ber_len_t ber_pvt_sb_copy_out( Sockbuf_Buf *sbb, char *buf, ber_len_t len ) { ber_len_t max; assert( buf != NULL ); assert( sbb != NULL ); #if 0 assert( sbb->buf_size > 0 ); #endif max = sbb->buf_end - sbb->buf_ptr; max = ( max < len) ? max : len; if ( max ) { AC_MEMCPY( buf, sbb->buf_base + sbb->buf_ptr, max ); sbb->buf_ptr += max; if ( sbb->buf_ptr >= sbb->buf_end ) { sbb->buf_ptr = sbb->buf_end = 0; } } return max; }
static int pack_sss_response_control( Operation *op, SlapReply *rs, LDAPControl **ctrlsp ) { LDAPControl *ctrl; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; struct berval bv; int rc; ber_init2( ber, NULL, LBER_USE_DER ); ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); /* Pack error code */ rc = ber_printf(ber, "{e}", rs->sr_err); if ( rc != -1) rc = ber_flatten2( ber, &bv, 0 ); if ( rc != -1 ) { ctrl = (LDAPControl *)op->o_tmpalloc( sizeof(LDAPControl)+ bv.bv_len, op->o_tmpmemctx ); ctrl->ldctl_oid = LDAP_CONTROL_SORTRESPONSE; ctrl->ldctl_iscritical = 0; ctrl->ldctl_value.bv_val = (char *)(ctrl+1); ctrl->ldctl_value.bv_len = bv.bv_len; AC_MEMCPY( ctrl->ldctl_value.bv_val, bv.bv_val, bv.bv_len ); ctrlsp[0] = ctrl; } else { ctrlsp[0] = NULL; rs->sr_err = LDAP_OTHER; } ber_free_buf( ber ); return rs->sr_err; }
/* Duplicate a set. If SLAP_SET_REFARR, is not set, the original array * with the original values is returned, otherwise the array is duplicated; * if SLAP_SET_REFVAL is set, also the values are duplicated. */ static BerVarray set_dup( SetCookie *cp, BerVarray set, unsigned flags ) { BerVarray newset = NULL; if ( set == NULL ) { return NULL; } if ( flags & SLAP_SET_REFARR ) { int i; for ( i = 0; !BER_BVISNULL( &set[ i ] ); i++ ) ; newset = cp->set_op->o_tmpcalloc( i + 1, sizeof( struct berval ), cp->set_op->o_tmpmemctx ); if ( newset == NULL ) { return NULL; } if ( flags & SLAP_SET_REFVAL ) { for ( i = 0; !BER_BVISNULL( &set[ i ] ); i++ ) { ber_dupbv_x( &newset[ i ], &set[ i ], cp->set_op->o_tmpmemctx ); } } else { AC_MEMCPY( newset, set, ( i + 1 ) * sizeof( struct berval ) ); } } else { newset = set; } return newset; }
/* * Compiles a substitution pattern */ struct rewrite_subst * rewrite_subst_compile( struct rewrite_info *info, const char *str ) { size_t subs_len; struct berval *subs = NULL, *tmps; struct rewrite_submatch *submatch = NULL; struct rewrite_subst *s = NULL; char *result, *begin, *p; int nsub = 0, l; assert( info != NULL ); assert( str != NULL ); result = strdup( str ); if ( result == NULL ) { return NULL; } /* * Take care of substitution string */ for ( p = begin = result, subs_len = 0; p[ 0 ] != '\0'; p++ ) { /* * Keep only single escapes '%' */ if ( !IS_REWRITE_SUBMATCH_ESCAPE( p[ 0 ] ) ) { continue; } if ( IS_REWRITE_SUBMATCH_ESCAPE( p[ 1 ] ) ) { /* Pull &p[1] over p, including the trailing '\0' */ AC_MEMCPY((char *)p, &p[ 1 ], strlen( p ) ); continue; } tmps = ( struct berval * )realloc( subs, sizeof( struct berval )*( nsub + 1 ) ); if ( tmps == NULL ) { goto cleanup; } subs = tmps; /* * I think an `if l > 0' at runtime is better outside than * inside a function call ... */ l = p - begin; if ( l > 0 ) { subs_len += l; subs[ nsub ].bv_len = l; subs[ nsub ].bv_val = malloc( l + 1 ); if ( subs[ nsub ].bv_val == NULL ) { goto cleanup; } AC_MEMCPY( subs[ nsub ].bv_val, begin, l ); subs[ nsub ].bv_val[ l ] = '\0'; } else { subs[ nsub ].bv_val = NULL; subs[ nsub ].bv_len = 0; } /* * Substitution pattern */ if ( isdigit( (unsigned char) p[ 1 ] ) ) { struct rewrite_submatch *tmpsm; int d = p[ 1 ] - '0'; /* * Add a new value substitution scheme */ tmpsm = ( struct rewrite_submatch * )realloc( submatch, sizeof( struct rewrite_submatch )*( nsub + 1 ) ); if ( tmpsm == NULL ) { goto cleanup; } submatch = tmpsm; submatch[ nsub ].ls_submatch = d; /* * If there is no argument, use default * (substitute substring as is) */ if ( p[ 2 ] != '{' ) { submatch[ nsub ].ls_type = REWRITE_SUBMATCH_ASIS; submatch[ nsub ].ls_map = NULL; begin = ++p + 1; } else { struct rewrite_map *map; submatch[ nsub ].ls_type = REWRITE_SUBMATCH_XMAP; map = rewrite_xmap_parse( info, p + 3, (const char **)&begin ); if ( map == NULL ) { goto cleanup; } submatch[ nsub ].ls_map = map; p = begin - 1; } /* * Map with args ... */ } else if ( p[ 1 ] == '{' ) { struct rewrite_map *map; struct rewrite_submatch *tmpsm; map = rewrite_map_parse( info, p + 2, (const char **)&begin ); if ( map == NULL ) { goto cleanup; } p = begin - 1; /* * Add a new value substitution scheme */ tmpsm = ( struct rewrite_submatch * )realloc( submatch, sizeof( struct rewrite_submatch )*( nsub + 1 ) ); if ( tmpsm == NULL ) { goto cleanup; } submatch = tmpsm; submatch[ nsub ].ls_type = REWRITE_SUBMATCH_MAP_W_ARG; submatch[ nsub ].ls_map = map; /* * Escape '%' ... */ } else if ( p[ 1 ] == '%' ) { AC_MEMCPY( &p[ 1 ], &p[ 2 ], strlen( &p[ 1 ] ) ); continue; } else { goto cleanup; } nsub++; } /* * Last part of string */ tmps = (struct berval * )realloc( subs, sizeof( struct berval )*( nsub + 1 ) ); if ( tmps == NULL ) { /* * XXX need to free the value subst stuff! */ free( subs ); goto cleanup; } subs = tmps; l = p - begin; if ( l > 0 ) { subs_len += l; subs[ nsub ].bv_len = l; subs[ nsub ].bv_val = malloc( l + 1 ); if ( subs[ nsub ].bv_val == NULL ) { free( subs ); goto cleanup; } AC_MEMCPY( subs[ nsub ].bv_val, begin, l ); subs[ nsub ].bv_val[ l ] = '\0'; } else { subs[ nsub ].bv_val = NULL; subs[ nsub ].bv_len = 0; } s = calloc( sizeof( struct rewrite_subst ), 1 ); if ( s == NULL ) { goto cleanup; } s->lt_subs_len = subs_len; s->lt_subs = subs; s->lt_num_submatch = nsub; s->lt_submatch = submatch; cleanup:; free( result ); return s; }
/* * Substitutes a portion of rewritten string according to substitution * pattern using submatches */ int rewrite_subst_apply( struct rewrite_info *info, struct rewrite_op *op, struct rewrite_subst *subst, const char *string, const regmatch_t *match, struct berval *val ) { struct berval *submatch = NULL; char *res = NULL; int n = 0, l, cl; int rc = REWRITE_REGEXEC_OK; assert( info != NULL ); assert( op != NULL ); assert( subst != NULL ); assert( string != NULL ); assert( match != NULL ); assert( val != NULL ); assert( val->bv_val == NULL ); val->bv_val = NULL; val->bv_len = 0; /* * Prepare room for submatch expansion */ if ( subst->lt_num_submatch > 0 ) { submatch = calloc( sizeof( struct berval ), subst->lt_num_submatch ); if ( submatch == NULL ) { return REWRITE_REGEXEC_ERR; } } /* * Resolve submatches (simple subst, map expansion and so). */ for ( n = 0, l = 0; n < subst->lt_num_submatch; n++ ) { struct berval key = { 0, NULL }; submatch[ n ].bv_val = NULL; /* * Get key */ switch ( subst->lt_submatch[ n ].ls_type ) { case REWRITE_SUBMATCH_ASIS: case REWRITE_SUBMATCH_XMAP: rc = submatch_copy( &subst->lt_submatch[ n ], string, match, &key ); if ( rc != REWRITE_SUCCESS ) { rc = REWRITE_REGEXEC_ERR; goto cleanup; } break; case REWRITE_SUBMATCH_MAP_W_ARG: switch ( subst->lt_submatch[ n ].ls_map->lm_type ) { case REWRITE_MAP_GET_OP_VAR: case REWRITE_MAP_GET_SESN_VAR: case REWRITE_MAP_GET_PARAM: rc = REWRITE_SUCCESS; break; default: rc = rewrite_subst_apply( info, op, subst->lt_submatch[ n ].ls_map->lm_subst, string, match, &key); } if ( rc != REWRITE_SUCCESS ) { goto cleanup; } break; default: Debug( LDAP_DEBUG_ANY, "Not Implemented\n", 0, 0, 0 ); rc = REWRITE_ERR; break; } if ( rc != REWRITE_SUCCESS ) { rc = REWRITE_REGEXEC_ERR; goto cleanup; } /* * Resolve key */ switch ( subst->lt_submatch[ n ].ls_type ) { case REWRITE_SUBMATCH_ASIS: submatch[ n ] = key; rc = REWRITE_SUCCESS; break; case REWRITE_SUBMATCH_XMAP: rc = rewrite_xmap_apply( info, op, subst->lt_submatch[ n ].ls_map, &key, &submatch[ n ] ); free( key.bv_val ); key.bv_val = NULL; break; case REWRITE_SUBMATCH_MAP_W_ARG: rc = rewrite_map_apply( info, op, subst->lt_submatch[ n ].ls_map, &key, &submatch[ n ] ); free( key.bv_val ); key.bv_val = NULL; break; default: /* * When implemented, this might return the * exit status of a rewrite context, * which may include a stop, or an * unwilling to perform */ rc = REWRITE_ERR; break; } if ( rc != REWRITE_SUCCESS ) { rc = REWRITE_REGEXEC_ERR; goto cleanup; } /* * Increment the length of the resulting string */ l += submatch[ n ].bv_len; } /* * Alloc result buffer */ l += subst->lt_subs_len; res = malloc( l + 1 ); if ( res == NULL ) { rc = REWRITE_REGEXEC_ERR; goto cleanup; } /* * Apply submatches (possibly resolved thru maps) */ for ( n = 0, cl = 0; n < subst->lt_num_submatch; n++ ) { if ( subst->lt_subs[ n ].bv_val != NULL ) { AC_MEMCPY( res + cl, subst->lt_subs[ n ].bv_val, subst->lt_subs[ n ].bv_len ); cl += subst->lt_subs[ n ].bv_len; } AC_MEMCPY( res + cl, submatch[ n ].bv_val, submatch[ n ].bv_len ); cl += submatch[ n ].bv_len; } if ( subst->lt_subs[ n ].bv_val != NULL ) { AC_MEMCPY( res + cl, subst->lt_subs[ n ].bv_val, subst->lt_subs[ n ].bv_len ); cl += subst->lt_subs[ n ].bv_len; } res[ cl ] = '\0'; val->bv_val = res; val->bv_len = l; cleanup:; if ( submatch ) { for ( ; --n >= 0; ) { if ( submatch[ n ].bv_val ) { free( submatch[ n ].bv_val ); } } free( submatch ); } return rc; }
/* Return values: -1: error, 0: no operation performed or the answer is false, * 1: successful operation or the answer is true */ int ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg ) { Sockbuf_IO_Desc *p; int ret = 0; assert( sb != NULL ); assert( SOCKBUF_VALID( sb ) ); switch ( opt ) { case LBER_SB_OPT_HAS_IO: p = sb->sb_iod; while ( p && p->sbiod_io != (Sockbuf_IO *)arg ) { p = p->sbiod_next; } if ( p ) { ret = 1; } break; case LBER_SB_OPT_GET_FD: if ( arg != NULL ) { *((ber_socket_t *)arg) = sb->sb_fd; } ret = ( sb->sb_fd == AC_SOCKET_INVALID ? -1 : 1); break; case LBER_SB_OPT_SET_FD: sb->sb_fd = *((ber_socket_t *)arg); ret = 1; break; case LBER_SB_OPT_SET_NONBLOCK: ret = ber_pvt_socket_set_nonblock( sb->sb_fd, arg != NULL) ? -1 : 1; break; case LBER_SB_OPT_DRAIN: { /* Drain the data source to enable possible errors (e.g. * TLS) to be propagated to the upper layers */ char buf[LBER_MIN_BUFF_SIZE]; do { ret = ber_int_sb_read( sb, buf, sizeof( buf ) ); } while ( ret == sizeof( buf ) ); ret = 1; } break; case LBER_SB_OPT_NEEDS_READ: ret = ( sb->sb_trans_needs_read ? 1 : 0 ); break; case LBER_SB_OPT_NEEDS_WRITE: ret = ( sb->sb_trans_needs_write ? 1 : 0 ); break; case LBER_SB_OPT_GET_MAX_INCOMING: if ( arg != NULL ) { *((ber_len_t *)arg) = sb->sb_max_incoming; } ret = 1; break; case LBER_SB_OPT_SET_MAX_INCOMING: sb->sb_max_incoming = *((ber_len_t *)arg); ret = 1; break; case LBER_SB_OPT_UNGET_BUF: #ifdef LDAP_PF_LOCAL_SENDMSG sb->sb_ungetlen = ((struct berval *)arg)->bv_len; if ( sb->sb_ungetlen <= sizeof( sb->sb_ungetbuf )) { AC_MEMCPY( sb->sb_ungetbuf, ((struct berval *)arg)->bv_val, sb->sb_ungetlen ); ret = 1; } else { sb->sb_ungetlen = 0; ret = -1; } #endif break; default: ret = sb->sb_iod->sbiod_io->sbi_ctrl( sb->sb_iod, opt, arg ); break; } return ret; }
int bdb_idl_fetch_key( BackendDB *be, DB *db, DB_TXN *txn, DBT *key, ID *ids, DBC **saved_cursor, int get_flag ) { struct bdb_info *bdb = (struct bdb_info *) be->be_private; int rc; DBT data, key2, *kptr; DBC *cursor; ID *i; void *ptr; size_t len; int rc2; int flags = bdb->bi_db_opflags | DB_MULTIPLE; int opflag; /* If using BerkeleyDB 4.0, the buf must be large enough to * grab the entire IDL in one get(), otherwise BDB will leak * resources on subsequent get's. We can safely call get() * twice - once for the data, and once to get the DB_NOTFOUND * result meaning there's no more data. See ITS#2040 for details. * This bug is fixed in BDB 4.1 so a smaller buffer will work if * stack space is too limited. * * configure now requires Berkeley DB 4.1. */ #if DB_VERSION_FULL < 0x04010000 # define BDB_ENOUGH 5 #else /* We sometimes test with tiny IDLs, and BDB always wants buffers * that are at least one page in size. */ # if BDB_IDL_DB_SIZE < 4096 # define BDB_ENOUGH 2048 # else # define BDB_ENOUGH 1 # endif #endif ID buf[BDB_IDL_DB_SIZE*BDB_ENOUGH]; char keybuf[16]; Debug( LDAP_DEBUG_ARGS, "bdb_idl_fetch_key: %s\n", bdb_show_key( key, keybuf ), 0, 0 ); assert( ids != NULL ); if ( saved_cursor && *saved_cursor ) { opflag = DB_NEXT; } else if ( get_flag == LDAP_FILTER_GE ) { opflag = DB_SET_RANGE; } else if ( get_flag == LDAP_FILTER_LE ) { opflag = DB_FIRST; } else { opflag = DB_SET; } /* only non-range lookups can use the IDL cache */ if ( bdb->bi_idl_cache_size && opflag == DB_SET ) { rc = bdb_idl_cache_get( bdb, db, key, ids ); if ( rc != LDAP_NO_SUCH_OBJECT ) return rc; } DBTzero( &data ); data.data = buf; data.ulen = sizeof(buf); data.flags = DB_DBT_USERMEM; /* If we're not reusing an existing cursor, get a new one */ if( opflag != DB_NEXT ) { rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags ); if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " "cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 ); return rc; } } else { cursor = *saved_cursor; } /* If this is a LE lookup, save original key so we can determine * when to stop. If this is a GE lookup, save the key since it * will be overwritten. */ if ( get_flag == LDAP_FILTER_LE || get_flag == LDAP_FILTER_GE ) { DBTzero( &key2 ); key2.flags = DB_DBT_USERMEM; key2.ulen = sizeof(keybuf); key2.data = keybuf; key2.size = key->size; AC_MEMCPY( keybuf, key->data, key->size ); kptr = &key2; } else { kptr = key; } len = key->size; rc = cursor->c_get( cursor, kptr, &data, flags | opflag ); /* skip presence key on range inequality lookups */ while (rc == 0 && kptr->size != len) { rc = cursor->c_get( cursor, kptr, &data, flags | DB_NEXT_NODUP ); } /* If we're doing a LE compare and the new key is greater than * our search key, we're done */ if (rc == 0 && get_flag == LDAP_FILTER_LE && memcmp( kptr->data, key->data, key->size ) > 0 ) { rc = DB_NOTFOUND; } if (rc == 0) { i = ids; while (rc == 0) { u_int8_t *j; DB_MULTIPLE_INIT( ptr, &data ); while (ptr) { DB_MULTIPLE_NEXT(ptr, &data, j, len); if (j) { ++i; BDB_DISK2ID( j, i ); } } rc = cursor->c_get( cursor, key, &data, flags | DB_NEXT_DUP ); } if ( rc == DB_NOTFOUND ) rc = 0; ids[0] = i - ids; /* On disk, a range is denoted by 0 in the first element */ if (ids[1] == 0) { if (ids[0] != BDB_IDL_RANGE_SIZE) { Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " "range size mismatch: expected %d, got %ld\n", BDB_IDL_RANGE_SIZE, ids[0], 0 ); cursor->c_close( cursor ); return -1; } BDB_IDL_RANGE( ids, ids[2], ids[3] ); } data.size = BDB_IDL_SIZEOF(ids); } if ( saved_cursor && rc == 0 ) { if ( !*saved_cursor ) *saved_cursor = cursor; rc2 = 0; } else rc2 = cursor->c_close( cursor ); if (rc2) { Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " "close failed: %s (%d)\n", db_strerror(rc2), rc2, 0 ); return rc2; } if( rc == DB_NOTFOUND ) { return rc; } else if( rc != 0 ) { Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " "get failed: %s (%d)\n", db_strerror(rc), rc, 0 ); return rc; } else if ( data.size == 0 || data.size % sizeof( ID ) ) { /* size not multiple of ID size */ Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " "odd size: expected %ld multiple, got %ld\n", (long) sizeof( ID ), (long) data.size, 0 ); return -1; } else if ( data.size != BDB_IDL_SIZEOF(ids) ) { /* size mismatch */ Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " "get size mismatch: expected %ld, got %ld\n", (long) ((1 + ids[0]) * sizeof( ID )), (long) data.size, 0 ); return -1; } if ( bdb->bi_idl_cache_max_size ) { bdb_idl_cache_put( bdb, db, key, ids, rc ); } return rc; }