int hdb_dn2id( Operation *op, struct berval *in, EntryInfo *ei, DB_TXN *txn, DB_LOCK *lock ) { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; DB *db = bdb->bi_dn2id->bdi_db; DBT key, data; DBC *cursor; int rc = 0, nrlen; diskNode *d; char *ptr; unsigned char dlen[2]; ID idp, parentID; Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id(\"%s\")\n", in->bv_val, 0, 0 ); nrlen = dn_rdnlen( op->o_bd, in ); if (!nrlen) nrlen = in->bv_len; DBTzero(&key); key.size = sizeof(ID); key.data = &idp; key.ulen = sizeof(ID); key.flags = DB_DBT_USERMEM; parentID = ( ei->bei_parent != NULL ) ? ei->bei_parent->bei_id : 0; BDB_ID2DISK( parentID, &idp ); DBTzero(&data); data.size = sizeof(diskNode) + nrlen - sizeof(ID) - 1; data.ulen = data.size * 3; data.dlen = data.ulen; data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags ); if ( rc ) return rc; d = op->o_tmpalloc( data.size * 3, op->o_tmpmemctx ); d->nrdnlen[1] = nrlen & 0xff; d->nrdnlen[0] = (nrlen >> 8) | 0x80; dlen[0] = d->nrdnlen[0]; dlen[1] = d->nrdnlen[1]; ptr = lutil_strncopy( d->nrdn, in->bv_val, nrlen ); *ptr = '\0'; data.data = d; rc = bdb_dn2id_lock( bdb, in, 0, txn, lock ); if ( rc ) goto func_leave; rc = cursor->c_get( cursor, &key, &data, DB_GET_BOTH_RANGE ); if ( rc == 0 && (dlen[1] != d->nrdnlen[1] || dlen[0] != d->nrdnlen[0] || strncmp( d->nrdn, in->bv_val, nrlen ))) { rc = DB_NOTFOUND; } if ( rc == 0 ) { ptr = (char *) data.data + data.size - sizeof(ID); BDB_DISK2ID( ptr, &ei->bei_id ); ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - nrlen; ptr = d->nrdn + nrlen + 1; ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn ); if ( ei->bei_parent != NULL && !ei->bei_parent->bei_dkids ) { db_recno_t dkids; /* How many children does the parent have? */ /* FIXME: do we need to lock the parent * entryinfo? Seems safe... */ cursor->c_count( cursor, &dkids, 0 ); ei->bei_parent->bei_dkids = dkids; } } func_leave: cursor->c_close( cursor ); op->o_tmpfree( d, op->o_tmpmemctx ); if( rc != 0 ) { Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: get failed: %s (%d)\n", db_strerror( rc ), rc, 0 ); } else { Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: got id=0x%lx\n", ei->bei_id, 0, 0 ); } return rc; }
static int dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli ) { Attribute *a, *id = NULL; slap_callback cb; Operation o = *op; SlapReply r = { REP_SEARCH }; struct berval *url; Entry *e; slap_mask_t e_flags; int opattrs, userattrs; dynlist_sc_t dlc = { 0 }; dynlist_map_t *dlm; a = attrs_find( rs->sr_entry->e_attrs, dli->dli_ad ); if ( a == NULL ) { /* FIXME: error? */ return SLAP_CB_CONTINUE; } #ifndef SLAP_OPATTRS opattrs = ( rs->sr_attrs == NULL ) ? 0 : an_find( rs->sr_attrs, slap_bv_operational_attrs ); userattrs = ( rs->sr_attrs == NULL ) ? 1 : an_find( rs->sr_attrs, slap_bv_user_attrs ); #else /* SLAP_OPATTRS */ opattrs = SLAP_OPATTRS( rs->sr_attr_flags ); userattrs = SLAP_USERATTRS( rs->sr_attr_flags ); #endif /* SLAP_OPATTRS */ /* Don't generate member list if it wasn't requested */ for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) { AttributeDescription *ad = dlm->dlm_mapped_ad ? dlm->dlm_mapped_ad : dlm->dlm_member_ad; if ( userattrs || ad_inlist( ad, rs->sr_attrs ) ) break; } if ( dli->dli_dlm && !dlm ) return SLAP_CB_CONTINUE; if ( ad_dgIdentity && ( id = attrs_find( rs->sr_entry->e_attrs, ad_dgIdentity ))) { Attribute *authz = NULL; /* if not rootdn and dgAuthz is present, * check if user can be authorized as dgIdentity */ if ( ad_dgAuthz && !BER_BVISEMPTY( &id->a_nvals[0] ) && !be_isroot( op ) && ( authz = attrs_find( rs->sr_entry->e_attrs, ad_dgAuthz ) ) ) { if ( slap_sasl_matches( op, authz->a_nvals, &o.o_ndn, &o.o_ndn ) != LDAP_SUCCESS ) { return SLAP_CB_CONTINUE; } } o.o_dn = id->a_vals[0]; o.o_ndn = id->a_nvals[0]; o.o_groups = NULL; } e_flags = rs->sr_flags; if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) { e = entry_dup( rs->sr_entry ); e_flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED ); } else { e = rs->sr_entry; } dlc.dlc_e = e; dlc.dlc_dli = dli; cb.sc_private = &dlc; cb.sc_response = dynlist_sc_update; cb.sc_cleanup = NULL; cb.sc_next = NULL; o.o_callback = &cb; o.ors_deref = LDAP_DEREF_NEVER; o.ors_limit = NULL; o.ors_tlimit = SLAP_NO_LIMIT; o.ors_slimit = SLAP_NO_LIMIT; for ( url = a->a_nvals; !BER_BVISNULL( url ); url++ ) { LDAPURLDesc *lud = NULL; int i, j; struct berval dn; int rc; BER_BVZERO( &o.o_req_dn ); BER_BVZERO( &o.o_req_ndn ); o.ors_filter = NULL; o.ors_attrs = NULL; BER_BVZERO( &o.ors_filterstr ); if ( ldap_url_parse( url->bv_val, &lud ) != LDAP_URL_SUCCESS ) { /* FIXME: error? */ continue; } if ( lud->lud_host != NULL ) { /* FIXME: host not allowed; reject as illegal? */ Debug( LDAP_DEBUG_ANY, "dynlist_prepare_entry(\"%s\"): " "illegal URI \"%s\"\n", e->e_name.bv_val, url->bv_val, 0 ); goto cleanup; } if ( lud->lud_dn == NULL ) { /* note that an empty base is not honored in terms * of defaultSearchBase, because select_backend() * is not aware of the defaultSearchBase option; * this can be useful in case of a database serving * the empty suffix */ BER_BVSTR( &dn, "" ); } else { ber_str2bv( lud->lud_dn, 0, 0, &dn ); } rc = dnPrettyNormal( NULL, &dn, &o.o_req_dn, &o.o_req_ndn, op->o_tmpmemctx ); if ( rc != LDAP_SUCCESS ) { /* FIXME: error? */ goto cleanup; } o.ors_scope = lud->lud_scope; for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) { if ( dlm->dlm_mapped_ad != NULL ) { break; } } if ( dli->dli_dlm && !dlm ) { /* if ( lud->lud_attrs != NULL ), * the URL should be ignored */ o.ors_attrs = slap_anlist_no_attrs; } else if ( lud->lud_attrs == NULL ) { o.ors_attrs = rs->sr_attrs; } else { for ( i = 0; lud->lud_attrs[i]; i++) /* just count */ ; o.ors_attrs = op->o_tmpcalloc( i + 1, sizeof( AttributeName ), op->o_tmpmemctx ); for ( i = 0, j = 0; lud->lud_attrs[i]; i++) { const char *text = NULL; ber_str2bv( lud->lud_attrs[i], 0, 0, &o.ors_attrs[j].an_name ); o.ors_attrs[j].an_desc = NULL; (void)slap_bv2ad( &o.ors_attrs[j].an_name, &o.ors_attrs[j].an_desc, &text ); /* FIXME: ignore errors... */ if ( rs->sr_attrs == NULL ) { if ( o.ors_attrs[j].an_desc != NULL && is_at_operational( o.ors_attrs[j].an_desc->ad_type ) ) { continue; } } else { if ( o.ors_attrs[j].an_desc != NULL && is_at_operational( o.ors_attrs[j].an_desc->ad_type ) ) { if ( !opattrs ) { continue; } if ( !ad_inlist( o.ors_attrs[j].an_desc, rs->sr_attrs ) ) { /* lookup if mapped -- linear search, * not very efficient unless list * is very short */ for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) { if ( dlm->dlm_member_ad == o.ors_attrs[j].an_desc ) { break; } } if ( dlm == NULL ) { continue; } } } else { if ( !userattrs && o.ors_attrs[j].an_desc != NULL && !ad_inlist( o.ors_attrs[j].an_desc, rs->sr_attrs ) ) { /* lookup if mapped -- linear search, * not very efficient unless list * is very short */ for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) { if ( dlm->dlm_member_ad == o.ors_attrs[j].an_desc ) { break; } } if ( dlm == NULL ) { continue; } } } } j++; } if ( j == 0 ) { goto cleanup; } BER_BVZERO( &o.ors_attrs[j].an_name ); } if ( lud->lud_filter == NULL ) { ber_dupbv_x( &o.ors_filterstr, &dli->dli_default_filter, op->o_tmpmemctx ); } else { struct berval flt; ber_str2bv( lud->lud_filter, 0, 0, &flt ); if ( dynlist_make_filter( op, &flt, &o.ors_filterstr ) ) { /* error */ goto cleanup; } } o.ors_filter = str2filter_x( op, o.ors_filterstr.bv_val ); if ( o.ors_filter == NULL ) { goto cleanup; } o.o_bd = select_backend( &o.o_req_ndn, 1 ); if ( o.o_bd && o.o_bd->be_search ) { #ifdef SLAP_OPATTRS r.sr_attr_flags = slap_attr_flags( o.ors_attrs ); #endif /* SLAP_OPATTRS */ (void)o.o_bd->be_search( &o, &r ); } cleanup:; if ( id ) { slap_op_groups_free( &o ); } if ( o.ors_filter ) { filter_free_x( &o, o.ors_filter, 1 ); } if ( o.ors_attrs && o.ors_attrs != rs->sr_attrs && o.ors_attrs != slap_anlist_no_attrs ) { op->o_tmpfree( o.ors_attrs, op->o_tmpmemctx ); } if ( !BER_BVISNULL( &o.o_req_dn ) ) { op->o_tmpfree( o.o_req_dn.bv_val, op->o_tmpmemctx ); } if ( !BER_BVISNULL( &o.o_req_ndn ) ) { op->o_tmpfree( o.o_req_ndn.bv_val, op->o_tmpmemctx ); } assert( BER_BVISNULL( &o.ors_filterstr ) || o.ors_filterstr.bv_val != lud->lud_filter ); op->o_tmpfree( o.ors_filterstr.bv_val, op->o_tmpmemctx ); ldap_free_urldesc( lud ); } rs->sr_entry = e; rs->sr_flags = e_flags; return SLAP_CB_CONTINUE; }
static int collect_cf( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; int rc = 1, idx; switch( c->op ) { case SLAP_CONFIG_EMIT: { collect_info *ci; for ( ci = on->on_bi.bi_private; ci; ci = ci->ci_next ) { struct berval bv; char *ptr; int len; /* calculate the length & malloc memory */ bv.bv_len = ci->ci_dn.bv_len + STRLENOF("\"\" "); for (idx=0; idx<ci->ci_ad_num; idx++) { bv.bv_len += ci->ci_ad[idx]->ad_cname.bv_len; if (idx<(ci->ci_ad_num-1)) { bv.bv_len++; } } bv.bv_val = ch_malloc( bv.bv_len + 1 ); /* copy the value and update len */ len = snprintf( bv.bv_val, bv.bv_len + 1, "\"%s\" ", ci->ci_dn.bv_val); ptr = bv.bv_val + len; for (idx=0; idx<ci->ci_ad_num; idx++) { ptr = lutil_strncopy( ptr, ci->ci_ad[idx]->ad_cname.bv_val, ci->ci_ad[idx]->ad_cname.bv_len); if (idx<(ci->ci_ad_num-1)) { *ptr++ = ','; } } *ptr = '\0'; bv.bv_len = ptr - bv.bv_val; ber_bvarray_add( &c->rvalue_vals, &bv ); rc = 0; } } break; case LDAP_MOD_DELETE: if ( c->valx == -1 ) { /* Delete entire attribute */ collect_info *ci; while (( ci = on->on_bi.bi_private )) { on->on_bi.bi_private = ci->ci_next; ch_free( ci->ci_dn.bv_val ); ch_free( ci ); } } else { /* Delete just one value */ collect_info **cip, *ci; int i; cip = (collect_info **)&on->on_bi.bi_private; ci = *cip; for ( i=0; i < c->valx; i++ ) { cip = &ci->ci_next; ci = *cip; } *cip = ci->ci_next; ch_free( ci->ci_dn.bv_val ); ch_free( ci ); } rc = 0; break; case SLAP_CONFIG_ADD: case LDAP_MOD_ADD: { collect_info *ci; struct berval bv, dn; const char *text; int idx, count=0; char *arg; /* count delimiters in attribute argument */ arg = strtok(c->argv[2], ","); while (arg!=NULL) { count++; arg = strtok(NULL, ","); } /* validate and normalize dn */ ber_str2bv( c->argv[1], 0, 0, &bv ); if ( dnNormalize( 0, NULL, NULL, &bv, &dn, NULL ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s invalid DN: \"%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; } /* check for duplicate DNs */ for ( ci = (collect_info *)on->on_bi.bi_private; ci; ci = ci->ci_next ) { /* If new DN is longest, there are no possible matches */ if ( dn.bv_len > ci->ci_dn.bv_len ) { ci = NULL; break; } if ( bvmatch( &dn, &ci->ci_dn )) { break; } } if ( ci ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s DN already configured: \"%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; } /* allocate config info with room for attribute array */ ci = ch_malloc( sizeof( collect_info ) + sizeof( AttributeDescription * ) * count ); /* load attribute description for attribute list */ arg = c->argv[2]; for( idx=0; idx<count; idx++) { ci->ci_ad[idx] = NULL; if ( slap_str2ad( arg, &ci->ci_ad[idx], &text ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s attribute description unknown: \"%s\"", c->argv[0], arg); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg, 0 ); ch_free( ci ); return ARG_BAD_CONF; } while(*arg!='\0') { arg++; /* skip to end of argument */ } if (idx<count-1) { arg++; /* skip inner delimiters */ } } /* The on->on_bi.bi_private pointer can be used for * anything this instance of the overlay needs. */ ci->ci_ad[count] = NULL; ci->ci_ad_num = count; ci->ci_dn = dn; /* creates list of ci's ordered by dn length */ insert_ordered ( on, ci ); /* New ci wasn't simply appended to end, adjust its * position in the config entry's a_vals */ if ( c->ca_entry && ci->ci_next ) { Attribute *a = attr_find( c->ca_entry->e_attrs, collectcfg[0].ad ); if ( a ) { struct berval bv, nbv; collect_info *c2 = (collect_info *)on->on_bi.bi_private; int i, j; for ( i=0; c2 != ci; i++, c2 = c2->ci_next ); bv = a->a_vals[a->a_numvals-1]; nbv = a->a_nvals[a->a_numvals-1]; for ( j=a->a_numvals-1; j>i; j-- ) { a->a_vals[j] = a->a_vals[j-1]; a->a_nvals[j] = a->a_nvals[j-1]; } a->a_vals[j] = bv; a->a_nvals[j] = nbv; } } rc = 0; } } return rc; }
/* * Convert a delimited string into a list of AttributeNames; add * on to an existing list if it was given. If the string is not * a valid attribute name, if a '-' is prepended it is skipped * and the remaining name is tried again; if a '@' (or '+') is * prepended, an objectclass name is searched instead; if a '!' * is prepended, the objectclass name is negated. * * NOTE: currently, if a valid attribute name is not found, the * same string is also checked as valid objectclass name; however, * this behavior is deprecated. */ AttributeName * str2anlist( AttributeName *an, char *in, const char *brkstr ) { char *str; char *s; char *lasts; int i, j; const char *text; AttributeName *anew; /* find last element in list */ i = 0; if ( an != NULL ) { for ( i = 0; !BER_BVISNULL( &an[ i ].an_name ) ; i++) ; } /* protect the input string from strtok */ str = ch_strdup( in ); /* Count words in string */ j = 1; for ( s = str; *s; s++ ) { if ( strchr( brkstr, *s ) != NULL ) { j++; } } an = ch_realloc( an, ( i + j + 1 ) * sizeof( AttributeName ) ); anew = an + i; for ( s = ldap_pvt_strtok( str, brkstr, &lasts ); s != NULL; s = ldap_pvt_strtok( NULL, brkstr, &lasts ) ) { /* put a stop mark */ BER_BVZERO( &anew[1].an_name ); anew->an_desc = NULL; anew->an_oc = NULL; anew->an_flags = 0; ber_str2bv(s, 0, 1, &anew->an_name); slap_bv2ad(&anew->an_name, &anew->an_desc, &text); if ( !anew->an_desc ) { switch( anew->an_name.bv_val[0] ) { case '-': { struct berval adname; adname.bv_len = anew->an_name.bv_len - 1; adname.bv_val = &anew->an_name.bv_val[1]; slap_bv2ad(&adname, &anew->an_desc, &text); if ( !anew->an_desc ) { goto reterr; } } break; case '@': case '+': /* (deprecated) */ case '!': { struct berval ocname; ocname.bv_len = anew->an_name.bv_len - 1; ocname.bv_val = &anew->an_name.bv_val[1]; anew->an_oc = oc_bvfind( &ocname ); if ( !anew->an_oc ) { goto reterr; } if ( anew->an_name.bv_val[0] == '!' ) { anew->an_flags |= SLAP_AN_OCEXCLUDE; } } break; default: /* old (deprecated) way */ anew->an_oc = oc_bvfind( &anew->an_name ); if ( !anew->an_oc ) { goto reterr; } } } anew->an_flags |= SLAP_AN_OCINITED; anew++; } BER_BVZERO( &anew->an_name ); free( str ); return( an ); reterr: anlist_free( an, 1, NULL ); /* * overwrites input string * on error! */ strcpy( in, s ); free( str ); return NULL; }
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; }
/* * FIXME: error return must be handled in a cleaner way ... */ int meta_back_op_result( metaconn_t *mc, Operation *op, SlapReply *rs, int candidate, ber_int_t msgid, time_t timeout, ldap_back_send_t sendok ) { metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; const char *save_text = rs->sr_text, *save_matched = rs->sr_matched; BerVarray save_ref = rs->sr_ref; LDAPControl **save_ctrls = rs->sr_ctrls; void *matched_ctx = NULL; char *matched = NULL; char *text = NULL; char **refs = NULL; LDAPControl **ctrls = NULL; assert( mc != NULL ); rs->sr_text = NULL; rs->sr_matched = NULL; rs->sr_ref = NULL; rs->sr_ctrls = NULL; if ( candidate != META_TARGET_NONE ) { metatarget_t *mt = mi->mi_targets[ candidate ]; metasingleconn_t *msc = &mc->mc_conns[ candidate ]; if ( LDAP_ERR_OK( rs->sr_err ) ) { int rc; struct timeval tv; LDAPMessage *res = NULL; time_t stoptime = (time_t)(-1); int timeout_err = op->o_protocol >= LDAP_VERSION3 ? LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER; const char *timeout_text = "Operation timed out"; /* if timeout is not specified, compute and use * the one specific to the ongoing operation */ if ( timeout == (time_t)(-1) ) { slap_op_t opidx = slap_req2op( op->o_tag ); if ( opidx == SLAP_OP_SEARCH ) { if ( op->ors_tlimit <= 0 ) { timeout = 0; } else { timeout = op->ors_tlimit; timeout_err = LDAP_TIMELIMIT_EXCEEDED; timeout_text = NULL; } } else { timeout = mt->mt_timeout[ opidx ]; } } /* better than nothing :) */ if ( timeout == 0 ) { if ( mi->mi_idle_timeout ) { timeout = mi->mi_idle_timeout; } else if ( mi->mi_conn_ttl ) { timeout = mi->mi_conn_ttl; } } if ( timeout ) { stoptime = op->o_time + timeout; } LDAP_BACK_TV_SET( &tv ); retry:; rc = ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res ); switch ( rc ) { case 0: if ( timeout && ldap_time_steady() > stoptime ) { (void)meta_back_cancel( mc, op, rs, msgid, candidate, sendok ); rs->sr_err = timeout_err; rs->sr_text = timeout_text; break; } LDAP_BACK_TV_SET( &tv ); ldap_pvt_thread_yield(); goto retry; case -1: ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE, &rs->sr_err ); break; /* otherwise get the result; if it is not * LDAP_SUCCESS, record it in the reply * structure (this includes * LDAP_COMPARE_{TRUE|FALSE}) */ default: /* only touch when activity actually took place... */ if ( mi->mi_idle_timeout != 0 && msc->msc_time < op->o_time ) { msc->msc_time = op->o_time; } rc = ldap_parse_result( msc->msc_ld, res, &rs->sr_err, &matched, &text, &refs, &ctrls, 1 ); res = NULL; if ( rc == LDAP_SUCCESS ) { rs->sr_text = text; } else { rs->sr_err = rc; } rs->sr_err = slap_map_api2result( rs ); /* RFC 4511: referrals can only appear * if result code is LDAP_REFERRAL */ if ( refs != NULL && refs[ 0 ] != NULL && refs[ 0 ][ 0 ] != '\0' ) { if ( rs->sr_err != LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s meta_back_op_result[%d]: " "got referrals with err=%d\n", op->o_log_prefix, candidate, rs->sr_err ); } else { int i; for ( i = 0; refs[ i ] != NULL; i++ ) /* count */ ; rs->sr_ref = op->o_tmpalloc( sizeof( struct berval ) * ( i + 1 ), op->o_tmpmemctx ); for ( i = 0; refs[ i ] != NULL; i++ ) { ber_str2bv( refs[ i ], 0, 0, &rs->sr_ref[ i ] ); } BER_BVZERO( &rs->sr_ref[ i ] ); } } else if ( rs->sr_err == LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s meta_back_op_result[%d]: " "got err=%d with null " "or empty referrals\n", op->o_log_prefix, candidate, rs->sr_err ); rs->sr_err = LDAP_NO_SUCH_OBJECT; } if ( ctrls != NULL ) { rs->sr_ctrls = ctrls; } } assert( res == NULL ); } /* if the error in the reply structure is not * LDAP_SUCCESS, try to map it from client * to server error */ if ( !LDAP_ERR_OK( rs->sr_err ) ) { rs->sr_err = slap_map_api2result( rs ); /* internal ops ( op->o_conn == NULL ) * must not reply to client */ if ( op->o_conn && !op->o_do_not_cache && matched ) { /* record the (massaged) matched * DN into the reply structure */ rs->sr_matched = matched; } } if ( META_BACK_TGT_QUARANTINE( mt ) ) { meta_back_quarantine( op, rs, candidate ); } } else { int i, err = rs->sr_err; for ( i = 0; i < mi->mi_ntargets; i++ ) { metasingleconn_t *msc = &mc->mc_conns[ i ]; char *xtext = NULL; char *xmatched = NULL; if ( msc->msc_ld == NULL ) { continue; } rs->sr_err = LDAP_SUCCESS; ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE, &rs->sr_err ); if ( rs->sr_err != LDAP_SUCCESS ) { /* * better check the type of error. In some cases * (search ?) it might be better to return a * success if at least one of the targets gave * positive result ... */ ldap_get_option( msc->msc_ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, &xtext ); if ( xtext != NULL && xtext [ 0 ] == '\0' ) { ldap_memfree( xtext ); xtext = NULL; } ldap_get_option( msc->msc_ld, LDAP_OPT_MATCHED_DN, &xmatched ); if ( xmatched != NULL && xmatched[ 0 ] == '\0' ) { ldap_memfree( xmatched ); xmatched = NULL; } rs->sr_err = slap_map_api2result( rs ); if ( DebugTest( LDAP_DEBUG_ANY ) ) { char buf[ SLAP_TEXT_BUFLEN ]; snprintf( buf, sizeof( buf ), "meta_back_op_result[%d] " "err=%d text=\"%s\" matched=\"%s\"", i, rs->sr_err, ( xtext ? xtext : "" ), ( xmatched ? xmatched : "" ) ); Debug( LDAP_DEBUG_ANY, "%s %s.\n", op->o_log_prefix, buf ); } /* * FIXME: need to rewrite "match" (need rwinfo) */ switch ( rs->sr_err ) { default: err = rs->sr_err; if ( xtext != NULL ) { if ( text ) { ldap_memfree( text ); } text = xtext; xtext = NULL; } if ( xmatched != NULL ) { if ( matched ) { ldap_memfree( matched ); } matched = xmatched; xmatched = NULL; } break; } if ( xtext ) { ldap_memfree( xtext ); } if ( xmatched ) { ldap_memfree( xmatched ); } } if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ i ] ) ) { meta_back_quarantine( op, rs, i ); } } if ( err != LDAP_SUCCESS ) { rs->sr_err = err; } } if ( matched != NULL ) { struct berval dn, pdn; ber_str2bv( matched, 0, 0, &dn ); if ( dnPretty( NULL, &dn, &pdn, op->o_tmpmemctx ) == LDAP_SUCCESS ) { ldap_memfree( matched ); matched_ctx = op->o_tmpmemctx; matched = pdn.bv_val; } rs->sr_matched = matched; } if ( rs->sr_err == LDAP_UNAVAILABLE ) { if ( !( sendok & LDAP_BACK_RETRYING ) ) { if ( op->o_conn && ( sendok & LDAP_BACK_SENDERR ) ) { if ( rs->sr_text == NULL ) rs->sr_text = "Proxy operation retry failed"; send_ldap_result( op, rs ); } } } else if ( op->o_conn && ( ( ( sendok & LDAP_BACK_SENDOK ) && LDAP_ERR_OK( rs->sr_err ) ) || ( ( sendok & LDAP_BACK_SENDERR ) && !LDAP_ERR_OK( rs->sr_err ) ) ) ) { send_ldap_result( op, rs ); } if ( matched ) { op->o_tmpfree( (char *)rs->sr_matched, matched_ctx ); } if ( text ) { ldap_memfree( text ); } if ( rs->sr_ref ) { op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx ); rs->sr_ref = NULL; } if ( refs ) { ber_memvfree( (void **)refs ); } if ( ctrls ) { assert( rs->sr_ctrls != NULL ); ldap_controls_free( ctrls ); } rs->sr_text = save_text; rs->sr_matched = save_matched; rs->sr_ref = save_ref; rs->sr_ctrls = save_ctrls; return( LDAP_ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err ); }
int slapauth( int argc, char **argv ) { int rc = EXIT_SUCCESS; const char *progname = "slapauth"; Connection conn = {0}; OperationBuffer opbuf; Operation *op; void *thrctx; slap_tool_init( progname, SLAPAUTH, argc, argv ); argv = &argv[ optind ]; argc -= optind; thrctx = ldap_pvt_thread_pool_context(); connection_fake_init( &conn, &opbuf, thrctx ); op = &opbuf.ob_op; conn.c_sasl_bind_mech = mech; if ( !BER_BVISNULL( &authzID ) ) { struct berval authzdn; rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn, SLAP_GETDN_AUTHZID ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "authzID: <%s> check failed %d (%s)\n", authzID.bv_val, rc, ldap_err2string( rc ) ); rc = 1; BER_BVZERO( &authzID ); goto destroy; } authzID = authzdn; } if ( !BER_BVISNULL( &authcID ) ) { if ( !BER_BVISNULL( &authzID ) || argc == 0 ) { rc = do_check( &conn, op, &authcID ); goto destroy; } for ( ; argc--; argv++ ) { struct berval authzdn; ber_str2bv( argv[ 0 ], 0, 0, &authzID ); rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn, SLAP_GETDN_AUTHZID ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "authzID: <%s> check failed %d (%s)\n", authzID.bv_val, rc, ldap_err2string( rc ) ); rc = -1; BER_BVZERO( &authzID ); if ( !continuemode ) { goto destroy; } } authzID = authzdn; rc = do_check( &conn, op, &authcID ); op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx ); BER_BVZERO( &authzID ); if ( rc && !continuemode ) { goto destroy; } } goto destroy; } for ( ; argc--; argv++ ) { struct berval id; ber_str2bv( argv[ 0 ], 0, 0, &id ); rc = do_check( &conn, op, &id ); if ( rc && !continuemode ) { goto destroy; } } destroy:; if ( !BER_BVISNULL( &authzID ) ) { op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx ); } if ( slap_tool_destroy()) rc = EXIT_FAILURE; return rc; }
static int nss_cf_gen(ConfigArgs *c) { slap_overinst *on = (slap_overinst *)c->bi; nssov_info *ni = on->on_bi.bi_private; nssov_mapinfo *mi; int i, j, rc = 0; slap_mask_t m; if ( c->op == SLAP_CONFIG_EMIT ) { switch(c->type) { case NSS_SSD: rc = 1; for (i=NM_alias;i<NM_NONE;i++) { struct berval scope; struct berval ssd; struct berval base; mi = &ni->ni_maps[i]; /* ignore all-default services */ if ( mi->mi_scope == LDAP_SCOPE_DEFAULT && bvmatch( &mi->mi_filter, &mi->mi_filter0 ) && BER_BVISNULL( &mi->mi_base )) continue; if ( BER_BVISNULL( &mi->mi_base )) base = ni->ni_db->be_nsuffix[0]; else base = mi->mi_base; ldap_pvt_scope2bv(mi->mi_scope == LDAP_SCOPE_DEFAULT ? LDAP_SCOPE_SUBTREE : mi->mi_scope, &scope); ssd.bv_len = STRLENOF(" ldap:///???") + nss_svcs[i].word.bv_len + base.bv_len + scope.bv_len + mi->mi_filter.bv_len; ssd.bv_val = ch_malloc( ssd.bv_len + 1 ); sprintf(ssd.bv_val, "%s ldap:///%s??%s?%s", nss_svcs[i].word.bv_val, base.bv_val, scope.bv_val, mi->mi_filter.bv_val ); ber_bvarray_add( &c->rvalue_vals, &ssd ); rc = 0; } break; case NSS_MAP: rc = 1; for (i=NM_alias;i<NM_NONE;i++) { mi = &ni->ni_maps[i]; for (j=0;!BER_BVISNULL(&mi->mi_attrkeys[j]);j++) { if ( ber_bvstrcasecmp(&mi->mi_attrkeys[j], &mi->mi_attrs[j].an_name)) { struct berval map; map.bv_len = nss_svcs[i].word.bv_len + mi->mi_attrkeys[j].bv_len + mi->mi_attrs[j].an_desc->ad_cname.bv_len + 2; map.bv_val = ch_malloc(map.bv_len + 1); sprintf(map.bv_val, "%s %s %s", nss_svcs[i].word.bv_val, mi->mi_attrkeys[j].bv_val, mi->mi_attrs[j].an_desc->ad_cname.bv_val ); ber_bvarray_add( &c->rvalue_vals, &map ); rc = 0; } } } break; case NSS_PAM: rc = mask_to_verbs( pam_opts, ni->ni_pam_opts, &c->rvalue_vals ); break; case NSS_PAMGROUP: if (!BER_BVISEMPTY( &ni->ni_pam_group_dn )) { value_add_one( &c->rvalue_vals, &ni->ni_pam_group_dn ); value_add_one( &c->rvalue_nvals, &ni->ni_pam_group_dn ); } else { rc = 1; } break; case NSS_PAMSESS: if (ni->ni_pam_sessions) { ber_bvarray_dup_x( &c->rvalue_vals, ni->ni_pam_sessions, NULL ); } else { rc = 1; } break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */ return 1; } switch( c->type ) { case NSS_SSD: { LDAPURLDesc *lud; i = verb_to_mask(c->argv[1], nss_svcs); if ( i == NM_NONE ) return 1; mi = &ni->ni_maps[i]; rc = ldap_url_parse(c->argv[2], &lud); if ( rc ) return 1; do { struct berval base; /* Must be LDAP scheme */ if (strcasecmp(lud->lud_scheme,"ldap")) { rc = 1; break; } /* Host part, attrs, and extensions must be empty */ if (( lud->lud_host && *lud->lud_host ) || lud->lud_attrs || lud->lud_exts ) { rc = 1; break; } ber_str2bv( lud->lud_dn,0,0,&base); rc = dnNormalize( 0,NULL,NULL,&base,&mi->mi_base,NULL); if ( rc ) break; if ( lud->lud_filter ) { /* steal this */ ber_str2bv( lud->lud_filter,0,0,&mi->mi_filter); lud->lud_filter = NULL; } mi->mi_scope = lud->lud_scope; } while(0); ldap_free_urldesc( lud ); } break; case NSS_MAP: i = verb_to_mask(c->argv[1], nss_svcs); if ( i == NM_NONE ) return 1; rc = 1; mi = &ni->ni_maps[i]; for (j=0; !BER_BVISNULL(&mi->mi_attrkeys[j]); j++) { if (!strcasecmp(c->argv[2],mi->mi_attrkeys[j].bv_val)) { AttributeDescription *ad = NULL; const char *text; rc = slap_str2ad( c->argv[3], &ad, &text); if ( rc == 0 ) { mi->mi_attrs[j].an_desc = ad; mi->mi_attrs[j].an_name = ad->ad_cname; } break; } } break; case NSS_PAM: m = ni->ni_pam_opts; i = verbs_to_mask(c->argc, c->argv, pam_opts, &m); if (i == 0) { ni->ni_pam_opts = m; if ((m & NI_PAM_USERHOST) && !nssov_pam_host_ad) { const char *text; i = slap_str2ad("host", &nssov_pam_host_ad, &text); if (i != LDAP_SUCCESS) { snprintf(c->cr_msg, sizeof(c->cr_msg), "nssov: host attr unknown: %s", text); Debug(LDAP_DEBUG_ANY,"%s\n",c->cr_msg,0,0); rc = 1; break; } } if ((m & (NI_PAM_USERSVC|NI_PAM_HOSTSVC)) && !nssov_pam_svc_ad) { const char *text; i = slap_str2ad("authorizedService", &nssov_pam_svc_ad, &text); if (i != LDAP_SUCCESS) { snprintf(c->cr_msg, sizeof(c->cr_msg), "nssov: authorizedService attr unknown: %s", text); Debug(LDAP_DEBUG_ANY,"%s\n",c->cr_msg,0,0); rc = 1; break; } } } else { rc = 1; } break; case NSS_PAMGROUP: ni->ni_pam_group_dn = c->value_ndn; ch_free( c->value_dn.bv_val ); break; case NSS_PAMSESS: ber_str2bv( c->argv[1], 0, 1, &c->value_bv ); ber_bvarray_add( &ni->ni_pam_sessions, &c->value_bv ); break; } return rc; }
/* * NOTE: the dn must be normalized */ int backsql_dn2id( Operation *op, SlapReply *rs, SQLHDBC dbh, struct berval *ndn, backsql_entryID *id, int matched, int muck ) { backsql_info *bi = op->o_bd->be_private; SQLHSTMT sth = SQL_NULL_HSTMT; BACKSQL_ROW_NTS row = { 0 }; RETCODE rc; int res; struct berval realndn = BER_BVNULL; /* TimesTen */ char upperdn[ BACKSQL_MAX_DN_LEN + 1 ]; struct berval tbbDN; int i, j; /* * NOTE: id can be NULL; in this case, the function * simply checks whether the DN can be successfully * turned into an ID, returning LDAP_SUCCESS for * positive cases, or the most appropriate error */ Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(\"%s\")%s%s\n", ndn->bv_val, id == NULL ? " (no ID expected)" : "", matched ? " matched expected" : "" ); if ( id ) { /* NOTE: trap inconsistencies */ assert( BER_BVISNULL( &id->eid_ndn ) ); } if ( ndn->bv_len > BACKSQL_MAX_DN_LEN ) { Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): DN length=%ld " "exceeds max DN length %d:\n", ndn->bv_val, ndn->bv_len, BACKSQL_MAX_DN_LEN ); return LDAP_OTHER; } /* return baseObject if available and matches */ /* FIXME: if ndn is already mucked, we cannot check this */ if ( bi->sql_baseObject != NULL && dn_match( ndn, &bi->sql_baseObject->e_nname ) ) { if ( id != NULL ) { #ifdef BACKSQL_ARBITRARY_KEY ber_dupbv_x( &id->eid_id, &backsql_baseObject_bv, op->o_tmpmemctx ); ber_dupbv_x( &id->eid_keyval, &backsql_baseObject_bv, op->o_tmpmemctx ); #else /* ! BACKSQL_ARBITRARY_KEY */ id->eid_id = BACKSQL_BASEOBJECT_ID; id->eid_keyval = BACKSQL_BASEOBJECT_KEYVAL; #endif /* ! BACKSQL_ARBITRARY_KEY */ id->eid_oc_id = BACKSQL_BASEOBJECT_OC; ber_dupbv_x( &id->eid_ndn, &bi->sql_baseObject->e_nname, op->o_tmpmemctx ); ber_dupbv_x( &id->eid_dn, &bi->sql_baseObject->e_name, op->o_tmpmemctx ); id->eid_next = NULL; } return LDAP_SUCCESS; } /* begin TimesTen */ assert( bi->sql_id_query != NULL ); Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): id_query \"%s\"\n", ndn->bv_val, bi->sql_id_query, 0 ); rc = backsql_Prepare( dbh, &sth, bi->sql_id_query, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "error preparing SQL:\n %s", ndn->bv_val, bi->sql_id_query, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); res = LDAP_OTHER; goto done; } realndn = *ndn; if ( muck ) { if ( backsql_api_dn2odbc( op, rs, &realndn ) ) { Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "backsql_api_dn2odbc(\"%s\") failed\n", ndn->bv_val, realndn.bv_val, 0 ); res = LDAP_OTHER; goto done; } } if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) { /* * Prepare an upper cased, byte reversed version * that can be searched using indexes */ for ( i = 0, j = realndn.bv_len - 1; realndn.bv_val[ i ]; i++, j--) { upperdn[ i ] = realndn.bv_val[ j ]; } upperdn[ i ] = '\0'; ldap_pvt_str2upper( upperdn ); Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "upperdn=\"%s\"\n", ndn->bv_val, upperdn, 0 ); ber_str2bv( upperdn, 0, 0, &tbbDN ); } else { if ( BACKSQL_USE_REVERSE_DN( bi ) ) { AC_MEMCPY( upperdn, realndn.bv_val, realndn.bv_len + 1 ); ldap_pvt_str2upper( upperdn ); Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "upperdn=\"%s\"\n", ndn->bv_val, upperdn, 0 ); ber_str2bv( upperdn, 0, 0, &tbbDN ); } else { tbbDN = realndn; } } rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &tbbDN ); if ( rc != SQL_SUCCESS) { /* end TimesTen */ Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "error binding dn=\"%s\" parameter:\n", ndn->bv_val, tbbDN.bv_val, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); res = LDAP_OTHER; goto done; } rc = SQLExecute( sth ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "error executing query (\"%s\", \"%s\"):\n", ndn->bv_val, bi->sql_id_query, tbbDN.bv_val ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); res = LDAP_OTHER; goto done; } backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx ); rc = SQLFetch( sth ); if ( BACKSQL_SUCCESS( rc ) ) { char buf[ SLAP_TEXT_BUFLEN ]; #ifdef LDAP_DEBUG snprintf( buf, sizeof(buf), "id=%s keyval=%s oc_id=%s dn=%s", row.cols[ 0 ], row.cols[ 1 ], row.cols[ 2 ], row.cols[ 3 ] ); Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): %s\n", ndn->bv_val, buf, 0 ); #endif /* LDAP_DEBUG */ res = LDAP_SUCCESS; if ( id != NULL ) { struct berval dn; id->eid_next = NULL; #ifdef BACKSQL_ARBITRARY_KEY ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id, op->o_tmpmemctx ); ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval, op->o_tmpmemctx ); #else /* ! BACKSQL_ARBITRARY_KEY */ if ( BACKSQL_STR2ID( &id->eid_id, row.cols[ 0 ], 0 ) != 0 ) { res = LDAP_OTHER; goto done; } if ( BACKSQL_STR2ID( &id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) { res = LDAP_OTHER; goto done; } #endif /* ! BACKSQL_ARBITRARY_KEY */ if ( BACKSQL_STR2ID( &id->eid_oc_id, row.cols[ 2 ], 0 ) != 0 ) { res = LDAP_OTHER; goto done; } ber_str2bv( row.cols[ 3 ], 0, 0, &dn ); if ( backsql_api_odbc2dn( op, rs, &dn ) ) { res = LDAP_OTHER; goto done; } res = dnPrettyNormal( NULL, &dn, &id->eid_dn, &id->eid_ndn, op->o_tmpmemctx ); if ( res != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_dn2id(\"%s\"): " "dnPrettyNormal failed (%d: %s)\n", realndn.bv_val, res, ldap_err2string( res ) ); /* cleanup... */ (void)backsql_free_entryID( id, 0, op->o_tmpmemctx ); } if ( dn.bv_val != row.cols[ 3 ] ) { free( dn.bv_val ); } } } else { res = LDAP_NO_SUCH_OBJECT; if ( matched ) { struct berval pdn = *ndn; /* * Look for matched */ rs->sr_matched = NULL; while ( !be_issuffix( op->o_bd, &pdn ) ) { char *matchedDN = NULL; dnParent( &pdn, &pdn ); /* * Empty DN ("") defaults to LDAP_SUCCESS */ rs->sr_err = backsql_dn2id( op, rs, dbh, &pdn, id, 0, 1 ); switch ( rs->sr_err ) { case LDAP_NO_SUCH_OBJECT: /* try another one */ break; case LDAP_SUCCESS: matchedDN = pdn.bv_val; /* fail over to next case */ default: rs->sr_err = LDAP_NO_SUCH_OBJECT; rs->sr_matched = matchedDN; goto done; } } } } done:; backsql_FreeRow_x( &row, op->o_tmpmemctx ); Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(\"%s\"): err=%d\n", ndn->bv_val, res, 0 ); if ( sth != SQL_NULL_HSTMT ) { SQLFreeStmt( sth, SQL_DROP ); } if ( !BER_BVISNULL( &realndn ) && realndn.bv_val != ndn->bv_val ) { ch_free( realndn.bv_val ); } return res; }
int backsql_split_pattern( const char *_pattern, BerVarray *split_pattern, int expected ) { char *pattern, *start, *end; struct berval bv; int rc = 0; #define SPLIT_CHAR '?' assert( _pattern != NULL ); assert( split_pattern != NULL ); pattern = ch_strdup( _pattern ); start = pattern; end = strchr( start, SPLIT_CHAR ); for ( ; start; expected-- ) { char *real_end = end; ber_len_t real_len; if ( real_end == NULL ) { real_end = start + strlen( start ); } else if ( real_end[ 1 ] == SPLIT_CHAR ) { expected++; memmove( real_end, real_end + 1, strlen( real_end ) ); end = strchr( real_end + 1, SPLIT_CHAR ); continue; } real_len = real_end - start; if ( real_len == 0 ) { ber_str2bv( "", 0, 1, &bv ); } else { ber_str2bv( start, real_len, 1, &bv ); } ber_bvarray_add( split_pattern, &bv ); if ( expected == 0 ) { if ( end != NULL ) { rc = -1; goto done; } break; } if ( end != NULL ) { start = end + 1; end = strchr( start, SPLIT_CHAR ); } } done:; ch_free( pattern ); return rc; }
int meta_back_db_open( Backend *be, ConfigReply *cr ) { metainfo_t *mi = (metainfo_t *)be->be_private; BackendInfo *bi; int i, not_always = 0, not_always_anon_proxyauthz = 0, not_always_anon_non_prescriptive = 0, rc; if ( mi->mi_ntargets == 0 ) { Debug( LDAP_DEBUG_ANY, "meta_back_db_open: no targets defined\n", 0, 0, 0 ); return 1; } bi = backend_info( "ldap" ); if ( !bi || !bi->bi_extra ) { Debug( LDAP_DEBUG_ANY, "meta_back_db_open: needs back-ldap\n", 0, 0, 0 ); return 1; } mi->mi_ldap_extra = (ldap_extra_t *)bi->bi_extra; for ( i = 0; i < mi->mi_ntargets; i++ ) { slap_bindconf sb = { BER_BVNULL }; metatarget_t *mt = mi->mi_targets[ i ]; ber_str2bv( mt->mt_uri, 0, 0, &sb.sb_uri ); sb.sb_version = mt->mt_version; sb.sb_method = LDAP_AUTH_SIMPLE; BER_BVSTR( &sb.sb_binddn, "" ); if ( META_BACK_TGT_T_F_DISCOVER( mt ) ) { rc = slap_discover_feature( &sb, slap_schema.si_ad_supportedFeatures->ad_cname.bv_val, LDAP_FEATURE_ABSOLUTE_FILTERS ); if ( rc == LDAP_COMPARE_TRUE ) { mt->mt_flags |= LDAP_BACK_F_T_F; } } if ( META_BACK_TGT_CANCEL_DISCOVER( mt ) ) { rc = slap_discover_feature( &sb, slap_schema.si_ad_supportedExtension->ad_cname.bv_val, LDAP_EXOP_CANCEL ); if ( rc == LDAP_COMPARE_TRUE ) { mt->mt_flags |= LDAP_BACK_F_CANCEL_EXOP; } } if ( not_always == 0 ) { if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) || mt->mt_idassert_authz != NULL ) { not_always = 1; } } if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) && !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) ) { Debug( LDAP_DEBUG_ANY, "meta_back_db_open(%s): " "target #%d inconsistent idassert configuration " "(likely authz=\"*\" used with \"non-prescriptive\" flag)\n", be->be_suffix[ 0 ].bv_val, i, 0 ); return 1; } if ( not_always_anon_proxyauthz == 0 ) { if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) { not_always_anon_proxyauthz = 1; } } if ( not_always_anon_non_prescriptive == 0 ) { if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) ) { not_always_anon_non_prescriptive = 1; } } } if ( not_always == 0 ) { mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS; } if ( not_always_anon_proxyauthz == 0 ) { mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ANON; } else if ( not_always_anon_non_prescriptive == 0 ) { mi->mi_flags |= META_BACK_F_PROXYAUTHZ_NOANON; } return 0; }
/* * call from within ldap_back_db_open() */ int ldap_back_monitor_db_open( BackendDB *be ) { ldapinfo_t *li = (ldapinfo_t *) be->be_private; char buf[ BACKMONITOR_BUFSIZE ]; Entry *e = NULL; monitor_callback_t *cb = NULL; struct berval suffix, *filter, *base; char *ptr; time_t now; char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; struct berval timestamp; int rc = 0; BackendInfo *mi; monitor_extra_t *mbe; if ( !SLAP_DBMONITORING( be ) ) { return 0; } /* check if monitor is configured and usable */ mi = backend_info( "monitor" ); if ( !mi || !mi->bi_extra ) { SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING; return 0; } mbe = mi->bi_extra; /* don't bother if monitor is not configured */ if ( !mbe->is_configured() ) { static int warning = 0; if ( warning++ == 0 ) { Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: " "monitoring disabled; " "configure monitor database to enable\n", 0, 0, 0 ); } return 0; } /* set up the fake subsystem that is used to create * the volatile connection entries */ li->li_monitor_info.lmi_mss.mss_name = "back-ldap"; li->li_monitor_info.lmi_mss.mss_flags = MONITOR_F_VOLATILE_CH; li->li_monitor_info.lmi_mss.mss_create = ldap_back_monitor_conn_create; li->li_monitor_info.lmi_li = li; li->li_monitor_info.lmi_scope = LDAP_SCOPE_SUBORDINATE; base = &li->li_monitor_info.lmi_base; BER_BVSTR( base, "cn=databases,cn=monitor" ); filter = &li->li_monitor_info.lmi_filter; BER_BVZERO( filter ); suffix.bv_len = ldap_bv2escaped_filter_value_len( &be->be_nsuffix[ 0 ] ); if ( suffix.bv_len == be->be_nsuffix[ 0 ].bv_len ) { suffix = be->be_nsuffix[ 0 ]; } else { ldap_bv2escaped_filter_value( &be->be_nsuffix[ 0 ], &suffix ); } filter->bv_len = STRLENOF( "(&" ) + li->li_monitor_info.lmi_more_filter.bv_len + STRLENOF( "(monitoredInfo=" ) + strlen( be->bd_info->bi_type ) + STRLENOF( ")(!(monitorOverlay=" ) + strlen( be->bd_info->bi_type ) + STRLENOF( "))(namingContexts:distinguishedNameMatch:=" ) + suffix.bv_len + STRLENOF( "))" ); ptr = filter->bv_val = ch_malloc( filter->bv_len + 1 ); ptr = lutil_strcopy( ptr, "(&" ); ptr = lutil_strncopy( ptr, li->li_monitor_info.lmi_more_filter.bv_val, li->li_monitor_info.lmi_more_filter.bv_len ); ptr = lutil_strcopy( ptr, "(monitoredInfo=" ); ptr = lutil_strcopy( ptr, be->bd_info->bi_type ); ptr = lutil_strcopy( ptr, ")(!(monitorOverlay=" ); ptr = lutil_strcopy( ptr, be->bd_info->bi_type ); ptr = lutil_strcopy( ptr, "))(namingContexts:distinguishedNameMatch:=" ); ptr = lutil_strncopy( ptr, suffix.bv_val, suffix.bv_len ); ptr = lutil_strcopy( ptr, "))" ); ptr[ 0 ] = '\0'; assert( ptr == &filter->bv_val[ filter->bv_len ] ); if ( suffix.bv_val != be->be_nsuffix[ 0 ].bv_val ) { ch_free( suffix.bv_val ); } now = slap_get_time(); timestamp.bv_val = timebuf; timestamp.bv_len = sizeof( timebuf ); slap_timestamp( &now, ×tamp ); /* caller (e.g. an overlay based on back-ldap) may want to use * a different RDN... */ if ( BER_BVISNULL( &li->li_monitor_info.lmi_rdn ) ) { ber_str2bv( "cn=Connections", 0, 1, &li->li_monitor_info.lmi_rdn ); } ptr = ber_bvchr( &li->li_monitor_info.lmi_rdn, '=' ); assert( ptr != NULL ); ptr[ 0 ] = '\0'; ptr++; snprintf( buf, sizeof( buf ), "dn: %s=%s\n" "objectClass: monitorContainer\n" "%s: %s\n" "creatorsName: %s\n" "createTimestamp: %s\n" "modifiersName: %s\n" "modifyTimestamp: %s\n", li->li_monitor_info.lmi_rdn.bv_val, ptr, li->li_monitor_info.lmi_rdn.bv_val, ptr, BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val, timestamp.bv_val, BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val, timestamp.bv_val ); e = str2entry( buf ); if ( e == NULL ) { rc = -1; goto cleanup; } ptr[ -1 ] = '='; /* add labeledURI and special, modifiable URI value */ if ( li->li_uri != NULL ) { struct berval bv; LDAPURLDesc *ludlist = NULL; int rc; rc = ldap_url_parselist_ext( &ludlist, li->li_uri, NULL, LDAP_PVT_URL_PARSE_NOEMPTY_HOST | LDAP_PVT_URL_PARSE_DEF_PORT ); if ( rc != LDAP_URL_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: " "unable to parse URI list (ignored)\n", 0, 0, 0 ); } else { for ( ; ludlist != NULL; ) { LDAPURLDesc *next = ludlist->lud_next; bv.bv_val = ldap_url_desc2str( ludlist ); assert( bv.bv_val != NULL ); ldap_free_urldesc( ludlist ); bv.bv_len = strlen( bv.bv_val ); attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI, &bv, NULL ); ch_free( bv.bv_val ); ludlist = next; } } ber_str2bv( li->li_uri, 0, 0, &bv ); attr_merge_normalize_one( e, ad_olmDbURIList, &bv, NULL ); } ber_dupbv( &li->li_monitor_info.lmi_nrdn, &e->e_nname ); cb = ch_calloc( sizeof( monitor_callback_t ), 1 ); cb->mc_update = ldap_back_monitor_update; cb->mc_modify = ldap_back_monitor_modify; cb->mc_free = ldap_back_monitor_free; cb->mc_private = (void *)li; rc = mbe->register_entry_parent( e, cb, (monitor_subsys_t *)&li->li_monitor_info, MONITOR_F_VOLATILE_CH, base, LDAP_SCOPE_SUBORDINATE, filter ); cleanup:; if ( rc != 0 ) { if ( cb != NULL ) { ch_free( cb ); cb = NULL; } if ( e != NULL ) { entry_free( e ); e = NULL; } if ( !BER_BVISNULL( filter ) ) { ch_free( filter->bv_val ); BER_BVZERO( filter ); } } /* store for cleanup */ li->li_monitor_info.lmi_cb = (void *)cb; if ( e != NULL ) { entry_free( e ); } return rc; }
static void * map_ldap_parse( const char *fname, int lineno, int argc, char **argv ) { struct ldap_map_data *data; char *p, *uri; assert( fname != NULL ); assert( argv != NULL ); data = calloc( sizeof( struct ldap_map_data ), 1 ); if ( data == NULL ) { return NULL; } if ( argc < 1 ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] ldap map needs URI\n%s", fname, lineno, "" ); free( data ); return NULL; } uri = argv[ 0 ]; if ( strncasecmp( uri, "uri=", STRLENOF( "uri=" ) ) == 0 ) { uri += STRLENOF( "uri=" ); } data->lm_url = strdup( uri ); if ( data->lm_url == NULL ) { map_ldap_free( data ); return NULL; } if ( ldap_url_parse( uri, &data->lm_lud ) != REWRITE_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] illegal URI '%s'\n", fname, lineno, argv[ 0 ] ); map_ldap_free( data ); return NULL; } /* trim everything after [host][:port] */ p = strchr( data->lm_url, '/' ); assert( p[ 1 ] == '/' ); if ( ( p = strchr( p + 2, '/' ) ) != NULL ) { p[ 0 ] = '\0'; } if ( data->lm_lud->lud_attrs == NULL ) { data->lm_attrs[ 0 ] = LDAP_NO_ATTRS; data->lm_wantdn = 1; } else { if ( data->lm_lud->lud_attrs[ 1 ] != NULL ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] only one attribute allowed in URI\n", fname, lineno ); map_ldap_free( data ); return NULL; } if ( strcasecmp( data->lm_lud->lud_attrs[ 0 ], "dn" ) == 0 || strcasecmp( data->lm_lud->lud_attrs[ 0 ], "entryDN" ) == 0 ) { ldap_memfree( data->lm_lud->lud_attrs[ 0 ] ); ldap_memfree( data->lm_lud->lud_attrs ); data->lm_lud->lud_attrs = NULL; data->lm_attrs[ 0 ] = LDAP_NO_ATTRS; data->lm_wantdn = 1; } else { data->lm_attrs[ 0 ] = data->lm_lud->lud_attrs[ 0 ]; } } data->lm_attrs[ 1 ] = NULL; /* safe defaults */ data->lm_version = LDAP_VERSION3; for ( argc--, argv++; argc > 0; argc--, argv++ ) { if ( strncasecmp( argv[ 0 ], "binddn=", STRLENOF( "binddn=" ) ) == 0 ) { char *p = argv[ 0 ] + STRLENOF( "binddn=" ); int l; if ( p[ 0 ] == '\"' || p [ 0 ] == '\'' ) { l = strlen( p ) - 2; p++; if ( p[ l ] != p[ 0 ] ) { map_ldap_free( data ); return NULL; } } else { l = strlen( p ); } data->lm_binddn = strdup( p ); if ( data->lm_binddn == NULL ) { map_ldap_free( data ); return NULL; } if ( data->lm_binddn[ l ] == '\"' || data->lm_binddn[ l ] == '\'' ) { data->lm_binddn[ l ] = '\0'; } /* deprecated */ } else if ( strncasecmp( argv[ 0 ], "bindpw=", STRLENOF( "bindpw=" ) ) == 0 ) { ber_str2bv( argv[ 0 ] + STRLENOF( "bindpw=" ), 0, 1, &data->lm_cred ); if ( data->lm_cred.bv_val == NULL ) { map_ldap_free( data ); return NULL; } } else if ( strncasecmp( argv[ 0 ], "credentials=", STRLENOF( "credentials=" ) ) == 0 ) { ber_str2bv( argv[ 0 ] + STRLENOF( "credentials=" ), 0, 1, &data->lm_cred ); if ( data->lm_cred.bv_val == NULL ) { map_ldap_free( data ); return NULL; } } else if ( strncasecmp( argv[ 0 ], "bindwhen=", STRLENOF( "bindwhen=" ) ) == 0 ) { char *p = argv[ 0 ] + STRLENOF( "bindwhen=" ); if ( strcasecmp( p, "now" ) == 0 ) { int rc; data->lm_when = MAP_LDAP_NOW; /* * Init LDAP handler ... */ rc = ldap_initialize( &data->lm_ld, data->lm_url ); if ( rc != LDAP_SUCCESS ) { map_ldap_free( data ); return NULL; } ldap_set_option( data->lm_ld, LDAP_OPT_PROTOCOL_VERSION, (void *)&data->lm_version ); #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_init( &data->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ } else if ( strcasecmp( p, "later" ) == 0 ) { data->lm_when = MAP_LDAP_LATER; #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_init( &data->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ } else if ( strcasecmp( p, "everytime" ) == 0 ) { data->lm_when = MAP_LDAP_EVERYTIME; } else { /* ignore ... */ } } else if ( strncasecmp( argv[ 0 ], "version=", STRLENOF( "version=" ) ) == 0 ) { if ( lutil_atoi( &data->lm_version, argv[ 0 ] + STRLENOF( "version=" ) ) ) { map_ldap_free( data ); return NULL; } switch ( data->lm_version ) { case LDAP_VERSION2: case LDAP_VERSION3: break; default: Debug( LDAP_DEBUG_ANY, "[%s:%d] unknown version %s\n", fname, lineno, p ); map_ldap_free( data ); return NULL; } } else { Debug( LDAP_DEBUG_ANY, "[%s:%d] unknown option %s (ignored)\n", fname, lineno, argv[0] ); } } if ( data->lm_when == MAP_LDAP_UNKNOWN ) { data->lm_when = MAP_LDAP_EVERYTIME; } return ( void * )data; }
int meta_back_db_open( Backend *be, ConfigReply *cr ) { metainfo_t *mi = (metainfo_t *)be->be_private; int i, not_always = 0, not_always_anon_proxyauthz = 0, not_always_anon_non_prescriptive = 0, rc; if ( mi->mi_ntargets == 0 ) { Debug( LDAP_DEBUG_ANY, "meta_back_db_open: no targets defined\n", 0, 0, 0 ); return 1; } for ( i = 0; i < mi->mi_ntargets; i++ ) { slap_bindconf sb = { BER_BVNULL }; metatarget_t *mt = mi->mi_targets[ i ]; struct berval mapped; ber_str2bv( mt->mt_uri, 0, 0, &sb.sb_uri ); sb.sb_version = mt->mt_version; sb.sb_method = LDAP_AUTH_SIMPLE; BER_BVSTR( &sb.sb_binddn, "" ); if ( META_BACK_TGT_T_F_DISCOVER( mt ) ) { rc = slap_discover_feature( &sb, slap_schema.si_ad_supportedFeatures->ad_cname.bv_val, LDAP_FEATURE_ABSOLUTE_FILTERS ); if ( rc == LDAP_COMPARE_TRUE ) { mt->mt_flags |= LDAP_BACK_F_T_F; } } if ( META_BACK_TGT_CANCEL_DISCOVER( mt ) ) { rc = slap_discover_feature( &sb, slap_schema.si_ad_supportedExtension->ad_cname.bv_val, LDAP_EXOP_CANCEL ); if ( rc == LDAP_COMPARE_TRUE ) { mt->mt_flags |= LDAP_BACK_F_CANCEL_EXOP; } } if ( not_always == 0 ) { if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) || mt->mt_idassert_authz != NULL ) { not_always = 1; } } if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) && !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) ) { Debug( LDAP_DEBUG_ANY, "meta_back_db_open(%s): " "target #%d inconsistent idassert configuration " "(likely authz=\"*\" used with \"non-prescriptive\" flag)\n", be->be_suffix[ 0 ].bv_val, i, 0 ); return 1; } if ( not_always_anon_proxyauthz == 0 ) { if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) { not_always_anon_proxyauthz = 1; } } if ( not_always_anon_non_prescriptive == 0 ) { if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) ) { not_always_anon_non_prescriptive = 1; } } BER_BVZERO( &mapped ); ldap_back_map( &mt->mt_rwmap.rwm_at, &slap_schema.si_ad_entryDN->ad_cname, &mapped, BACKLDAP_REMAP ); if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) { mt->mt_rep_flags |= REP_NO_ENTRYDN; } BER_BVZERO( &mapped ); ldap_back_map( &mt->mt_rwmap.rwm_at, &slap_schema.si_ad_subschemaSubentry->ad_cname, &mapped, BACKLDAP_REMAP ); if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) { mt->mt_rep_flags |= REP_NO_SUBSCHEMA; } } if ( not_always == 0 ) { mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS; } if ( not_always_anon_proxyauthz == 0 ) { mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ANON; } else if ( not_always_anon_non_prescriptive == 0 ) { mi->mi_flags |= META_BACK_F_PROXYAUTHZ_NOANON; } return 0; }
static int constraint_violation( constraint *c, struct berval *bv, Operation *op ) { if ((!c) || (!bv)) return LDAP_SUCCESS; switch (c->type) { case CONSTRAINT_SIZE: if (bv->bv_len > c->size) return LDAP_CONSTRAINT_VIOLATION; /* size violation */ break; case CONSTRAINT_REGEX: if (regexec(c->re, bv->bv_val, 0, NULL, 0) == REG_NOMATCH) return LDAP_CONSTRAINT_VIOLATION; /* regular expression violation */ break; case CONSTRAINT_URI: { Operation nop = *op; slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; slap_callback cb; int i; int found = 0; int rc; size_t len; struct berval filterstr; char *ptr; cb.sc_next = NULL; cb.sc_response = constraint_uri_cb; cb.sc_cleanup = NULL; cb.sc_private = &found; nop.o_protocol = LDAP_VERSION3; nop.o_tag = LDAP_REQ_SEARCH; nop.o_time = slap_get_time(); if (c->lud->lud_dn) { struct berval dn; ber_str2bv(c->lud->lud_dn, 0, 0, &dn); nop.o_req_dn = dn; nop.o_req_ndn = dn; nop.o_bd = select_backend(&nop.o_req_ndn, 1 ); if (!nop.o_bd) { return LDAP_NO_SUCH_OBJECT; /* unexpected error */ } if (!nop.o_bd->be_search) { return LDAP_OTHER; /* unexpected error */ } } else { nop.o_req_dn = nop.o_bd->be_nsuffix[0]; nop.o_req_ndn = nop.o_bd->be_nsuffix[0]; nop.o_bd = on->on_info->oi_origdb; } nop.o_do_not_cache = 1; nop.o_callback = &cb; nop.ors_scope = c->lud->lud_scope; nop.ors_deref = LDAP_DEREF_NEVER; nop.ors_slimit = SLAP_NO_LIMIT; nop.ors_tlimit = SLAP_NO_LIMIT; nop.ors_limit = NULL; nop.ors_attrsonly = 0; nop.ors_attrs = slap_anlist_no_attrs; len = STRLENOF("(&(") + c->filter.bv_len + STRLENOF(")(|"); for (i = 0; c->attrs[i]; i++) { len += STRLENOF("(") + c->attrs[i]->ad_cname.bv_len + STRLENOF("=") + bv->bv_len + STRLENOF(")"); } len += STRLENOF("))"); filterstr.bv_len = len; filterstr.bv_val = op->o_tmpalloc(len + 1, op->o_tmpmemctx); ptr = filterstr.bv_val + snprintf(filterstr.bv_val, len, "(&(%s)(|", c->lud->lud_filter); for (i = 0; c->attrs[i]; i++) { *ptr++ = '('; ptr = lutil_strcopy( ptr, c->attrs[i]->ad_cname.bv_val ); *ptr++ = '='; ptr = lutil_strcopy( ptr, bv->bv_val ); *ptr++ = ')'; } *ptr++ = ')'; *ptr++ = ')'; *ptr++ = '\0'; nop.ors_filterstr = filterstr; nop.ors_filter = str2filter_x(&nop, filterstr.bv_val); if ( nop.ors_filter == NULL ) { Debug( LDAP_DEBUG_ANY, "%s constraint_violation uri filter=\"%s\" invalid\n", op->o_log_prefix, filterstr.bv_val ); rc = LDAP_OTHER; } else { SlapReply nrs = { REP_RESULT }; Debug(LDAP_DEBUG_TRACE, "==> constraint_violation uri filter = %s\n", filterstr.bv_val); rc = nop.o_bd->be_search( &nop, &nrs ); Debug(LDAP_DEBUG_TRACE, "==> constraint_violation uri rc = %d, found = %d\n", rc, found); } op->o_tmpfree(filterstr.bv_val, op->o_tmpmemctx); if ((rc != LDAP_SUCCESS) && (rc != LDAP_NO_SUCH_OBJECT)) { return rc; /* unexpected error */ } if (!found) return LDAP_CONSTRAINT_VIOLATION; /* constraint violation */ break; } } return LDAP_SUCCESS; }
static int backsql_get_attr_vals( void *v_at, void *v_bsi ) { backsql_at_map_rec *at = v_at; backsql_srch_info *bsi = v_bsi; backsql_info *bi; RETCODE rc; SQLHSTMT sth = SQL_NULL_HSTMT; BACKSQL_ROW_NTS row; unsigned long i, k = 0, oldcount = 0, res = 0; #ifdef BACKSQL_COUNTQUERY unsigned count, j, append = 0; SQLLEN countsize = sizeof( count ); Attribute *attr = NULL; slap_mr_normalize_func *normfunc = NULL; #endif /* BACKSQL_COUNTQUERY */ #ifdef BACKSQL_PRETTY_VALIDATE slap_syntax_validate_func *validate = NULL; slap_syntax_transform_func *pretty = NULL; #endif /* BACKSQL_PRETTY_VALIDATE */ assert( at != NULL ); assert( bsi != NULL ); Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): " "oc=\"%s\" attr=\"%s\" keyval=" BACKSQL_IDFMT "\n", BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val, BACKSQL_IDARG(bsi->bsi_c_eid->eid_keyval) ); bi = (backsql_info *)bsi->bsi_op->o_bd->be_private; #ifdef BACKSQL_PRETTY_VALIDATE validate = at->bam_true_ad->ad_type->sat_syntax->ssyn_validate; pretty = at->bam_true_ad->ad_type->sat_syntax->ssyn_pretty; if ( validate == NULL && pretty == NULL ) { return 1; } #endif /* BACKSQL_PRETTY_VALIDATE */ #ifdef BACKSQL_COUNTQUERY if ( at->bam_true_ad->ad_type->sat_equality ) { normfunc = at->bam_true_ad->ad_type->sat_equality->smr_normalize; } /* Count how many rows will be returned. This avoids memory * fragmentation that can result from loading the values in * one by one and using realloc() */ rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_countquery, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): " "error preparing count query: %s\n", at->bam_countquery, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc ); return 1; } rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT, &bsi->bsi_c_eid->eid_keyval ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): " "error binding key value parameter\n", 0, 0, 0 ); SQLFreeStmt( sth, SQL_DROP ); return 1; } rc = SQLExecute( sth ); if ( ! BACKSQL_SUCCESS( rc ) ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): " "error executing attribute count query '%s'\n", at->bam_countquery, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); return 1; } SQLBindCol( sth, (SQLUSMALLINT)1, SQL_C_LONG, (SQLPOINTER)&count, (SQLINTEGER)sizeof( count ), &countsize ); rc = SQLFetch( sth ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): " "error fetch results of count query: %s\n", at->bam_countquery, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); return 1; } Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): " "number of values in query: %u\n", count, 0, 0 ); SQLFreeStmt( sth, SQL_DROP ); if ( count == 0 ) { return 1; } attr = attr_find( bsi->bsi_e->e_attrs, at->bam_true_ad ); if ( attr != NULL ) { BerVarray tmp; if ( attr->a_vals != NULL ) { oldcount = attr->a_numvals; } tmp = ch_realloc( attr->a_vals, ( oldcount + count + 1 ) * sizeof( struct berval ) ); if ( tmp == NULL ) { return 1; } attr->a_vals = tmp; memset( &attr->a_vals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) ); if ( normfunc ) { tmp = ch_realloc( attr->a_nvals, ( oldcount + count + 1 ) * sizeof( struct berval ) ); if ( tmp == NULL ) { return 1; } attr->a_nvals = tmp; memset( &attr->a_nvals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) ); } else { attr->a_nvals = attr->a_vals; } attr->a_numvals += count; } else { append = 1; /* Make space for the array of values */ attr = attr_alloc( at->bam_true_ad ); attr->a_numvals = count; attr->a_vals = ch_calloc( count + 1, sizeof( struct berval ) ); if ( attr->a_vals == NULL ) { Debug( LDAP_DEBUG_TRACE, "Out of memory!\n", 0,0,0 ); ch_free( attr ); return 1; } if ( normfunc ) { attr->a_nvals = ch_calloc( count + 1, sizeof( struct berval ) ); if ( attr->a_nvals == NULL ) { ch_free( attr->a_vals ); ch_free( attr ); return 1; } } else { attr->a_nvals = attr->a_vals; } } #endif /* BACKSQL_COUNTQUERY */ rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_query, 0 ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): " "error preparing query: %s\n", at->bam_query, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc ); #ifdef BACKSQL_COUNTQUERY if ( append ) { attr_free( attr ); } #endif /* BACKSQL_COUNTQUERY */ return 1; } rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT, &bsi->bsi_c_eid->eid_keyval ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): " "error binding key value parameter\n", 0, 0, 0 ); #ifdef BACKSQL_COUNTQUERY if ( append ) { attr_free( attr ); } #endif /* BACKSQL_COUNTQUERY */ return 1; } #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): " "query=\"%s\" keyval=" BACKSQL_IDFMT "\n", at->bam_query, BACKSQL_IDARG(bsi->bsi_c_eid->eid_keyval), 0 ); #endif /* BACKSQL_TRACE */ rc = SQLExecute( sth ); if ( ! BACKSQL_SUCCESS( rc ) ) { Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): " "error executing attribute query \"%s\"\n", at->bam_query, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); #ifdef BACKSQL_COUNTQUERY if ( append ) { attr_free( attr ); } #endif /* BACKSQL_COUNTQUERY */ return 1; } backsql_BindRowAsStrings_x( sth, &row, bsi->bsi_op->o_tmpmemctx ); #ifdef BACKSQL_COUNTQUERY j = oldcount; #endif /* BACKSQL_COUNTQUERY */ for ( rc = SQLFetch( sth ), k = 0; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ), k++ ) { for ( i = 0; i < (unsigned long)row.ncols; i++ ) { if ( row.value_len[ i ] > 0 ) { struct berval bv; int retval; #ifdef BACKSQL_TRACE AttributeDescription *ad = NULL; const char *text; retval = slap_bv2ad( &row.col_names[ i ], &ad, &text ); if ( retval != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "==>backsql_get_attr_vals(\"%s\"): " "unable to find AttributeDescription %s " "in schema (%d)\n", bsi->bsi_e->e_name.bv_val, row.col_names[ i ].bv_val, retval ); res = 1; goto done; } if ( ad != at->bam_ad ) { Debug( LDAP_DEBUG_ANY, "==>backsql_get_attr_vals(\"%s\"): " "column name %s differs from " "AttributeDescription %s\n", bsi->bsi_e->e_name.bv_val, ad->ad_cname.bv_val, at->bam_ad->ad_cname.bv_val ); res = 1; goto done; } #endif /* BACKSQL_TRACE */ /* ITS#3386, ITS#3113 - 20070308 * If a binary is fetched? * must use the actual size read * from the database. */ if ( BACKSQL_IS_BINARY( row.col_type[ i ] ) ) { #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_ANY, "==>backsql_get_attr_vals(\"%s\"): " "column name %s: data is binary; " "using database size %ld\n", bsi->bsi_e->e_name.bv_val, ad->ad_cname.bv_val, row.value_len[ i ] ); #endif /* BACKSQL_TRACE */ bv.bv_val = row.cols[ i ]; bv.bv_len = row.value_len[ i ]; } else { ber_str2bv( row.cols[ i ], 0, 0, &bv ); } #ifdef BACKSQL_PRETTY_VALIDATE if ( pretty ) { struct berval pbv; retval = pretty( at->bam_true_ad->ad_type->sat_syntax, &bv, &pbv, bsi->bsi_op->o_tmpmemctx ); bv = pbv; } else { retval = validate( at->bam_true_ad->ad_type->sat_syntax, &bv ); } if ( retval != LDAP_SUCCESS ) { char buf[ SLAP_TEXT_BUFLEN ]; /* FIXME: we're ignoring invalid values, * but we're accepting the attributes; * should we fail at all? */ snprintf( buf, sizeof( buf ), "unable to %s value #%lu " "of AttributeDescription %s", pretty ? "prettify" : "validate", k - oldcount, at->bam_ad->ad_cname.bv_val ); Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(\"%s\"): " "%s (%d)\n", bsi->bsi_e->e_name.bv_val, buf, retval ); continue; } #endif /* BACKSQL_PRETTY_VALIDATE */ #ifndef BACKSQL_COUNTQUERY (void)backsql_entry_addattr( bsi->bsi_e, at->bam_true_ad, &bv, bsi->bsi_op->o_tmpmemctx ); #else /* BACKSQL_COUNTQUERY */ if ( normfunc ) { struct berval nbv; retval = (*normfunc)( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, at->bam_true_ad->ad_type->sat_syntax, at->bam_true_ad->ad_type->sat_equality, &bv, &nbv, bsi->bsi_op->o_tmpmemctx ); if ( retval != LDAP_SUCCESS ) { char buf[ SLAP_TEXT_BUFLEN ]; /* FIXME: we're ignoring invalid values, * but we're accepting the attributes; * should we fail at all? */ snprintf( buf, sizeof( buf ), "unable to normalize value #%lu " "of AttributeDescription %s", k - oldcount, at->bam_ad->ad_cname.bv_val ); Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(\"%s\"): " "%s (%d)\n", bsi->bsi_e->e_name.bv_val, buf, retval ); #ifdef BACKSQL_PRETTY_VALIDATE if ( pretty ) { bsi->bsi_op->o_tmpfree( bv.bv_val, bsi->bsi_op->o_tmpmemctx ); } #endif /* BACKSQL_PRETTY_VALIDATE */ continue; } ber_dupbv( &attr->a_nvals[ j ], &nbv ); bsi->bsi_op->o_tmpfree( nbv.bv_val, bsi->bsi_op->o_tmpmemctx ); } ber_dupbv( &attr->a_vals[ j ], &bv ); assert( j < oldcount + count ); j++; #endif /* BACKSQL_COUNTQUERY */ #ifdef BACKSQL_PRETTY_VALIDATE if ( pretty ) { bsi->bsi_op->o_tmpfree( bv.bv_val, bsi->bsi_op->o_tmpmemctx ); } #endif /* BACKSQL_PRETTY_VALIDATE */ #ifdef BACKSQL_TRACE Debug( LDAP_DEBUG_TRACE, "prec=%d\n", (int)row.col_prec[ i ], 0, 0 ); } else { Debug( LDAP_DEBUG_TRACE, "NULL value " "in this row for attribute \"%s\"\n", row.col_names[ i ].bv_val, 0, 0 ); #endif /* BACKSQL_TRACE */ } } } #ifdef BACKSQL_COUNTQUERY if ( BER_BVISNULL( &attr->a_vals[ 0 ] ) ) { /* don't leave around attributes with no values */ attr_free( attr ); } else if ( append ) { Attribute **ap; for ( ap = &bsi->bsi_e->e_attrs; (*ap) != NULL; ap = &(*ap)->a_next ) /* goto last */ ; *ap = attr; } #endif /* BACKSQL_COUNTQUERY */ SQLFreeStmt( sth, SQL_DROP ); Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 ); if ( at->bam_next ) { res = backsql_get_attr_vals( at->bam_next, v_bsi ); } else { res = 1; } #ifdef BACKSQL_TRACE done:; #endif /* BACKSQL_TRACE */ backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx ); return res; }
int ldap_back_search( Operation *op, SlapReply *rs ) { ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; ldapconn_t *lc = NULL; struct timeval tv; time_t stoptime = (time_t)(-1); LDAPMessage *res, *e; int rc = 0, msgid; struct berval match = BER_BVNULL, filter = BER_BVNULL; int i, x; char **attrs = NULL; int freetext = 0, filter_undef = 0; int do_retry = 1, dont_retry = 0; LDAPControl **ctrls = NULL; char **references = NULL; rs_assert_ready( rs ); rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia, we can set rs = non-entry */ if ( !ldap_back_dobind( &lc, op, rs, LDAP_BACK_SENDERR ) ) { return rs->sr_err; } /* * FIXME: in case of values return filter, we might want * to map attrs and maybe rewrite value */ if ( op->ors_tlimit != SLAP_NO_LIMIT ) { tv.tv_sec = op->ors_tlimit; tv.tv_usec = 0; stoptime = op->o_time + op->ors_tlimit; } else { LDAP_BACK_TV_SET( &tv ); } i = 0; if ( op->ors_attrs ) { for ( ; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++ ) /* just count attrs */ ; } x = 0; if ( op->o_bd->be_extra_anlist ) { for ( ; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ ) /* just count attrs */ ; } if ( i > 0 || x > 0 ) { int j = 0; attrs = op->o_tmpalloc( ( i + x + 1 )*sizeof( char * ), op->o_tmpmemctx ); if ( attrs == NULL ) { rs->sr_err = LDAP_NO_MEMORY; rc = -1; goto finish; } if ( i > 0 ) { for ( i = 0; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++, j++ ) { attrs[ j ] = op->ors_attrs[i].an_name.bv_val; } } if ( x > 0 ) { for ( x = 0; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++, j++ ) { if ( op->o_bd->be_extra_anlist[x].an_desc && ad_inlist( op->o_bd->be_extra_anlist[x].an_desc, op->ors_attrs ) ) { continue; } attrs[ j ] = op->o_bd->be_extra_anlist[x].an_name.bv_val; } } attrs[ j ] = NULL; } ctrls = op->o_ctrls; rc = ldap_back_controls_add( op, rs, lc, &ctrls ); if ( rc != LDAP_SUCCESS ) { goto finish; } /* deal with <draft-zeilenga-ldap-t-f> filters */ filter = op->ors_filterstr; retry: /* this goes after retry because ldap_back_munge_filter() * optionally replaces RFC 4526 T-F filters (&) (|) * if already computed, they will be re-installed * by filter2bv_undef_x() later */ if ( !LDAP_BACK_T_F( li ) ) { ldap_back_munge_filter( op, &filter ); } rs->sr_err = ldap_pvt_search( lc->lc_ld, op->o_req_dn.bv_val, op->ors_scope, filter.bv_val, attrs, op->ors_attrsonly, ctrls, NULL, tv.tv_sec ? &tv : NULL, op->ors_slimit, op->ors_deref, &msgid ); ldap_pvt_thread_mutex_lock( &li->li_counter_mutex ); ldap_pvt_mp_add( li->li_ops_completed[ SLAP_OP_SEARCH ], 1 ); ldap_pvt_thread_mutex_unlock( &li->li_counter_mutex ); if ( rs->sr_err != LDAP_SUCCESS ) { switch ( rs->sr_err ) { case LDAP_SERVER_DOWN: if ( do_retry ) { do_retry = 0; if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) { goto retry; } } if ( lc == NULL ) { /* reset by ldap_back_retry ... */ rs->sr_err = slap_map_api2result( rs ); } else { rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND ); } goto finish; case LDAP_FILTER_ERROR: /* first try? */ if ( !filter_undef && strstr( filter.bv_val, "(?" ) && !LDAP_BACK_NOUNDEFFILTER( li ) ) { BER_BVZERO( &filter ); filter2bv_undef_x( op, op->ors_filter, 1, &filter ); filter_undef = 1; goto retry; } /* invalid filters return success with no data */ rs->sr_err = LDAP_SUCCESS; rs->sr_text = NULL; goto finish; default: rs->sr_err = slap_map_api2result( rs ); rs->sr_text = NULL; goto finish; } } /* if needed, initialize timeout */ if ( li->li_timeout[ SLAP_OP_SEARCH ] ) { if ( tv.tv_sec == 0 || tv.tv_sec > li->li_timeout[ SLAP_OP_SEARCH ] ) { tv.tv_sec = li->li_timeout[ SLAP_OP_SEARCH ]; tv.tv_usec = 0; } } /* We pull apart the ber result, stuff it into a slapd entry, and * let send_search_entry stuff it back into ber format. Slow & ugly, * but this is necessary for version matching, and for ACL processing. */ for ( rc = -2; rc != -1; rc = ldap_result( lc->lc_ld, msgid, LDAP_MSG_ONE, &tv, &res ) ) { /* check for abandon */ if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( lc ) ) { if ( rc > 0 ) { ldap_msgfree( res ); } (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); rc = SLAPD_ABANDON; goto finish; } if ( rc == 0 || rc == -2 ) { ldap_pvt_thread_yield(); /* check timeout */ if ( li->li_timeout[ SLAP_OP_SEARCH ] ) { if ( rc == 0 ) { (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); rs->sr_text = "Operation timed out"; rc = rs->sr_err = op->o_protocol >= LDAP_VERSION3 ? LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER; goto finish; } } else { LDAP_BACK_TV_SET( &tv ); } /* check time limit */ if ( op->ors_tlimit != SLAP_NO_LIMIT && slap_get_time() > stoptime ) { (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); rc = rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; goto finish; } continue; } else { /* only touch when activity actually took place... */ if ( li->li_idle_timeout ) { lc->lc_time = op->o_time; } /* don't retry any more */ dont_retry = 1; } if ( rc == LDAP_RES_SEARCH_ENTRY ) { Entry ent = { 0 }; struct berval bdn = BER_BVNULL; do_retry = 0; e = ldap_first_entry( lc->lc_ld, res ); rc = ldap_build_entry( op, e, &ent, &bdn ); if ( rc == LDAP_SUCCESS ) { ldap_get_entry_controls( lc->lc_ld, res, &rs->sr_ctrls ); rs->sr_entry = &ent; rs->sr_attrs = op->ors_attrs; rs->sr_operational_attrs = NULL; rs->sr_flags = 0; rs->sr_err = LDAP_SUCCESS; rc = rs->sr_err = send_search_entry( op, rs ); if ( rs->sr_ctrls ) { ldap_controls_free( rs->sr_ctrls ); rs->sr_ctrls = NULL; } rs->sr_entry = NULL; rs->sr_flags = 0; if ( !BER_BVISNULL( &ent.e_name ) ) { assert( ent.e_name.bv_val != bdn.bv_val ); op->o_tmpfree( ent.e_name.bv_val, op->o_tmpmemctx ); BER_BVZERO( &ent.e_name ); } if ( !BER_BVISNULL( &ent.e_nname ) ) { op->o_tmpfree( ent.e_nname.bv_val, op->o_tmpmemctx ); BER_BVZERO( &ent.e_nname ); } entry_clean( &ent ); } ldap_msgfree( res ); switch ( rc ) { case LDAP_SUCCESS: case LDAP_INSUFFICIENT_ACCESS: break; default: if ( rc == LDAP_UNAVAILABLE ) { rc = rs->sr_err = LDAP_OTHER; } else { (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND ); } goto finish; } } else if ( rc == LDAP_RES_SEARCH_REFERENCE ) { if ( LDAP_BACK_NOREFS( li ) ) { ldap_msgfree( res ); continue; } do_retry = 0; rc = ldap_parse_reference( lc->lc_ld, res, &references, &rs->sr_ctrls, 1 ); if ( rc != LDAP_SUCCESS ) { continue; } /* FIXME: there MUST be at least one */ if ( references && references[ 0 ] && references[ 0 ][ 0 ] ) { int cnt; for ( cnt = 0; references[ cnt ]; cnt++ ) /* NO OP */ ; /* FIXME: there MUST be at least one */ rs->sr_ref = op->o_tmpalloc( ( cnt + 1 ) * sizeof( struct berval ), op->o_tmpmemctx ); for ( cnt = 0; references[ cnt ]; cnt++ ) { ber_str2bv( references[ cnt ], 0, 0, &rs->sr_ref[ cnt ] ); } BER_BVZERO( &rs->sr_ref[ cnt ] ); /* ignore return value by now */ RS_ASSERT( !(rs->sr_flags & REP_ENTRY_MASK) ); rs->sr_entry = NULL; ( void )send_search_reference( op, rs ); } else { Debug( LDAP_DEBUG_ANY, "%s ldap_back_search: " "got SEARCH_REFERENCE " "with no referrals\n", op->o_log_prefix, 0, 0 ); } /* cleanup */ if ( references ) { ber_memvfree( (void **)references ); op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx ); rs->sr_ref = NULL; references = NULL; } if ( rs->sr_ctrls ) { ldap_controls_free( rs->sr_ctrls ); rs->sr_ctrls = NULL; } } else if ( rc == LDAP_RES_INTERMEDIATE ) { /* FIXME: response controls * are passed without checks */ rc = ldap_parse_intermediate( lc->lc_ld, res, (char **)&rs->sr_rspoid, &rs->sr_rspdata, &rs->sr_ctrls, 0 ); if ( rc != LDAP_SUCCESS ) { continue; } slap_send_ldap_intermediate( op, rs ); if ( rs->sr_rspoid != NULL ) { ber_memfree( (char *)rs->sr_rspoid ); rs->sr_rspoid = NULL; } if ( rs->sr_rspdata != NULL ) { ber_bvfree( rs->sr_rspdata ); rs->sr_rspdata = NULL; } if ( rs->sr_ctrls != NULL ) { ldap_controls_free( rs->sr_ctrls ); rs->sr_ctrls = NULL; } } else { char *err = NULL; rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err, &match.bv_val, &err, &references, &rs->sr_ctrls, 1 ); if ( rc == LDAP_SUCCESS ) { if ( err ) { rs->sr_text = err; freetext = 1; } } else { rs->sr_err = rc; } rs->sr_err = slap_map_api2result( rs ); /* RFC 4511: referrals can only appear * if result code is LDAP_REFERRAL */ if ( references && references[ 0 ] && references[ 0 ][ 0 ] ) { if ( rs->sr_err != LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s ldap_back_search: " "got referrals with err=%d\n", op->o_log_prefix, rs->sr_err, 0 ); } else { int cnt; for ( cnt = 0; references[ cnt ]; cnt++ ) /* NO OP */ ; rs->sr_ref = op->o_tmpalloc( ( cnt + 1 ) * sizeof( struct berval ), op->o_tmpmemctx ); for ( cnt = 0; references[ cnt ]; cnt++ ) { /* duplicating ...*/ ber_str2bv( references[ cnt ], 0, 0, &rs->sr_ref[ cnt ] ); } BER_BVZERO( &rs->sr_ref[ cnt ] ); } } else if ( rs->sr_err == LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s ldap_back_search: " "got err=%d with null " "or empty referrals\n", op->o_log_prefix, rs->sr_err, 0 ); rs->sr_err = LDAP_NO_SUCH_OBJECT; } if ( match.bv_val != NULL ) { match.bv_len = strlen( match.bv_val ); } rc = 0; break; } /* if needed, restore timeout */ if ( li->li_timeout[ SLAP_OP_SEARCH ] ) { if ( tv.tv_sec == 0 || tv.tv_sec > li->li_timeout[ SLAP_OP_SEARCH ] ) { tv.tv_sec = li->li_timeout[ SLAP_OP_SEARCH ]; tv.tv_usec = 0; } } } if ( rc == -1 ) { if ( dont_retry == 0 ) { if ( do_retry ) { do_retry = 0; if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) { goto retry; } } rs->sr_err = LDAP_SERVER_DOWN; rs->sr_err = slap_map_api2result( rs ); goto finish; } else if ( LDAP_BACK_ONERR_STOP( li ) ) { /* if onerr == STOP */ rs->sr_err = LDAP_SERVER_DOWN; rs->sr_err = slap_map_api2result( rs ); goto finish; } } /* * Rewrite the matched portion of the search base, if required */ if ( !BER_BVISNULL( &match ) && !BER_BVISEMPTY( &match ) ) { struct berval pmatch; if ( dnPretty( NULL, &match, &pmatch, op->o_tmpmemctx ) != LDAP_SUCCESS ) { pmatch.bv_val = match.bv_val; match.bv_val = NULL; } rs->sr_matched = pmatch.bv_val; rs->sr_flags |= REP_MATCHED_MUSTBEFREED; } finish:; if ( !BER_BVISNULL( &match ) ) { ber_memfree( match.bv_val ); } if ( rs->sr_v2ref ) { rs->sr_err = LDAP_REFERRAL; } if ( LDAP_BACK_QUARANTINE( li ) ) { ldap_back_quarantine( op, rs ); } if ( filter.bv_val != op->ors_filterstr.bv_val ) { op->o_tmpfree( filter.bv_val, op->o_tmpmemctx ); } #if 0 /* let send_ldap_result play cleanup handlers (ITS#4645) */ if ( rc != SLAPD_ABANDON ) #endif { send_ldap_result( op, rs ); } (void)ldap_back_controls_free( op, rs, &ctrls ); if ( rs->sr_ctrls ) { ldap_controls_free( rs->sr_ctrls ); rs->sr_ctrls = NULL; } if ( rs->sr_text ) { if ( freetext ) { ber_memfree( (char *)rs->sr_text ); } rs->sr_text = NULL; } if ( rs->sr_ref ) { op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx ); rs->sr_ref = NULL; } if ( references ) { ber_memvfree( (void **)references ); } if ( attrs ) { op->o_tmpfree( attrs, op->o_tmpmemctx ); } if ( lc != NULL ) { ldap_back_release_conn( li, lc ); } if ( rs->sr_err == LDAP_UNAVAILABLE && /* if we originally bound and wanted rebind-as-user, must drop * the connection now because we just discarded the credentials. * ITS#7464, #8142 */ LDAP_BACK_SAVECRED( li ) && SLAP_IS_AUTHZ_BACKEND( op ) ) rs->sr_err = SLAPD_DISCONNECT; return rs->sr_err; }
static int adremap_cf_dnv(ConfigArgs *c) { BackendDB *be = (BackendDB *)c->be; slap_overinst *on = (slap_overinst *)c->bi; adremap_info *ai = on->on_bi.bi_private; adremap_dnv *ad, **a2; int rc = ARG_BAD_CONF; switch(c->op) { case SLAP_CONFIG_EMIT: for (ad = ai->ai_dnv; ad; ad=ad->ad_next) { char *ptr; struct berval bv; bv.bv_len = ad->ad_dnattr->ad_cname.bv_len + ad->ad_deref->ad_cname.bv_len + ad->ad_newattr->ad_cname.bv_len + 2; bv.bv_len += ad->ad_group->soc_cname.bv_len + ad->ad_mapgrp->soc_cname.bv_len + ad->ad_refgrp->soc_cname.bv_len + 3; bv.bv_len += ad->ad_refbase.bv_len + 3; bv.bv_val = ch_malloc(bv.bv_len + 1); ptr = lutil_strcopy(bv.bv_val, ad->ad_dnattr->ad_cname.bv_val); *ptr++ = ' '; ptr = lutil_strcopy(ptr, ad->ad_deref->ad_cname.bv_val); *ptr++ = ' '; ptr = lutil_strcopy(ptr, ad->ad_newattr->ad_cname.bv_val); *ptr++ = ' '; ptr = lutil_strcopy(ptr, ad->ad_group->soc_cname.bv_val); *ptr++ = ' '; ptr = lutil_strcopy(ptr, ad->ad_mapgrp->soc_cname.bv_val); *ptr++ = ' '; ptr = lutil_strcopy(ptr, ad->ad_refgrp->soc_cname.bv_val); *ptr++ = ' '; *ptr++ = '"'; ptr = lutil_strcopy(ptr, ad->ad_refbase.bv_val); *ptr++ = '"'; *ptr = '\0'; ber_bvarray_add(&c->rvalue_vals, &bv); } if (ai->ai_dnv) rc = 0; break; case LDAP_MOD_DELETE: if (c->valx < 0) { for (ad = ai->ai_dnv; ad; ad=ai->ai_dnv) { ai->ai_dnv = ad->ad_next; ch_free(ad); } } else { int i; for (i=0, a2 = &ai->ai_dnv; i<c->valx; i++, a2 = &(*a2)->ad_next); ad = *a2; *a2 = ad->ad_next; ch_free(ad); } rc = 0; break; default: { const char *text; adremap_dnv av = {0}; struct berval dn; rc = slap_str2ad(c->argv[1], &av.ad_dnattr, &text); if (rc) break; if (av.ad_dnattr->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName) { rc = 1; snprintf(c->cr_msg, sizeof(c->cr_msg), "<%s> not a DN-valued attribute", c->argv[0]); Debug(LDAP_DEBUG_ANY, "%s: %s(%s)\n", c->log, c->cr_msg, c->argv[1]); break; } rc = slap_str2ad(c->argv[2], &av.ad_deref, &text); if (rc) break; rc = slap_str2ad(c->argv[3], &av.ad_newattr, &text); if (rc) break; av.ad_group = oc_find(c->argv[4]); if (!av.ad_group) { rc = 1; break; } av.ad_mapgrp = oc_find(c->argv[5]); if (!av.ad_mapgrp) { rc = 1; break; } av.ad_refgrp = oc_find(c->argv[6]); if (!av.ad_refgrp) { rc = 1; break; } ber_str2bv(c->argv[7], 0, 0, &dn); rc = dnNormalize(0, NULL, NULL, &dn, &av.ad_refbase, NULL); if (rc) break; for (a2 = &ai->ai_dnv; *a2; a2 = &(*a2)->ad_next); ad = ch_malloc(sizeof(adremap_dnv)); ad->ad_next = NULL; ad->ad_dnattr = av.ad_dnattr; ad->ad_deref = av.ad_deref; ad->ad_newattr = av.ad_newattr; ad->ad_group = av.ad_group; ad->ad_mapgrp = av.ad_mapgrp; ad->ad_refgrp = av.ad_refgrp; ad->ad_refbase = av.ad_refbase; *a2 = ad; break; } } return rc; }
static int allop_db_config( BackendDB *be, const char *fname, int lineno, int argc, char **argv ) { slap_overinst *on = (slap_overinst *)be->bd_info; allop_t *ao = (allop_t *)on->on_bi.bi_private; if ( strcasecmp( argv[ 0 ], "allop-uri" ) == 0 ) { LDAPURLDesc *lud; struct berval dn, ndn; int scope, rc = LDAP_SUCCESS; if ( argc != 2 ) { fprintf( stderr, "%s line %d: " "need exactly 1 arg " "in \"allop-uri <ldapURI>\" " "directive.\n", fname, lineno ); return 1; } if ( ldap_url_parse( argv[ 1 ], &lud ) != LDAP_URL_SUCCESS ) { return -1; } scope = lud->lud_scope; if ( scope == LDAP_SCOPE_DEFAULT ) { scope = LDAP_SCOPE_BASE; } if ( lud->lud_dn == NULL || lud->lud_dn[ 0 ] == '\0' ) { if ( scope == LDAP_SCOPE_BASE ) { BER_BVZERO( &ndn ); } else { ber_str2bv( "", 0, 1, &ndn ); } } else { ber_str2bv( lud->lud_dn, 0, 0, &dn ); rc = dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ); } ldap_free_urldesc( lud ); if ( rc != LDAP_SUCCESS ) { return -1; } if ( BER_BVISNULL( &ndn ) ) { /* rootDSE */ if ( ao != NULL ) { ch_free( ao->ao_ndn.bv_val ); ch_free( ao ); on->on_bi.bi_private = NULL; } } else { if ( ao == NULL ) { ao = ch_calloc( 1, sizeof( allop_t ) ); on->on_bi.bi_private = (void *)ao; } else { ch_free( ao->ao_ndn.bv_val ); } ao->ao_ndn = ndn; ao->ao_scope = scope; } } else { return SLAP_CONF_UNKNOWN; } return 0; }
int main( int argc, char **argv ) { int i; char *uri = NULL; char *host = "localhost"; char *dn = NULL; char *base = NULL; char *filter = "(objectClass=person)"; struct berval pass = { 0, NULL }; char *pwattr = NULL; int port = -1; int loops = LOOPS; int outerloops = 1; int force = 0; int chaserefs = 0; int noinit = 1; int delay = 0; /* extra action to do after bind... */ struct berval type[] = { BER_BVC( "tester=" ), BER_BVC( "add=" ), BER_BVC( "bind=" ), BER_BVC( "modify=" ), BER_BVC( "modrdn=" ), BER_BVC( "read=" ), BER_BVC( "search=" ), BER_BVNULL }; LDAPURLDesc *extra_ludp = NULL; tester_init( "slapd-bind", TESTER_BIND ); /* by default, tolerate invalid credentials */ tester_ignore_str2errlist( "INVALID_CREDENTIALS" ); while ( ( i = getopt( argc, argv, "a:B:b:D:Ff:H:h:Ii:L:l:p:t:w:" ) ) != EOF ) { switch ( i ) { case 'a': pwattr = optarg; break; case 'b': /* base DN of a tree of user DNs */ base = optarg; break; case 'B': { int c; for ( c = 0; type[c].bv_val; c++ ) { if ( strncasecmp( optarg, type[c].bv_val, type[c].bv_len ) == 0 ) { break; } } if ( type[c].bv_val == NULL ) { usage( argv[0], 'B' ); } switch ( c ) { case TESTER_TESTER: case TESTER_BIND: /* invalid */ usage( argv[0], 'B' ); case TESTER_SEARCH: { if ( ldap_url_parse( &optarg[type[c].bv_len], &extra_ludp ) != LDAP_URL_SUCCESS ) { usage( argv[0], 'B' ); } } break; case TESTER_ADDEL: case TESTER_MODIFY: case TESTER_MODRDN: case TESTER_READ: /* nothing to do */ break; default: assert( 0 ); } } break; case 'C': chaserefs++; break; case 'H': /* the server uri */ uri = optarg; break; case 'h': /* the servers host */ host = optarg; break; case 'i': tester_ignore_str2errlist( optarg ); break; case 'p': /* the servers port */ if ( lutil_atoi( &port, optarg ) != 0 ) { usage( argv[0], 'p' ); } break; case 'D': dn = optarg; break; case 'w': ber_str2bv( optarg, 0, 1, &pass ); memset( optarg, '*', pass.bv_len ); break; case 'l': /* the number of loops */ if ( lutil_atoi( &loops, optarg ) != 0 ) { usage( argv[0], 'l' ); } break; case 'L': /* the number of outerloops */ if ( lutil_atoi( &outerloops, optarg ) != 0 ) { usage( argv[0], 'L' ); } break; case 'f': filter = optarg; break; case 'F': force++; break; case 'I': /* reuse connection */ noinit = 0; break; case 't': /* sleep between binds */ if ( lutil_atoi( &delay, optarg ) != 0 ) { usage( argv[0], 't' ); } break; default: usage( argv[0], i ); break; } } if ( port == -1 && uri == NULL ) { usage( argv[0], '\0' ); } uri = tester_uri( uri, host, port ); for ( i = 0; i < outerloops; i++ ) { int rc; if ( base != NULL ) { rc = do_base( uri, dn, &pass, base, filter, pwattr, loops, force, chaserefs, noinit, delay, -1, NULL ); } else { rc = do_bind( uri, dn, &pass, loops, force, chaserefs, noinit, NULL, -1, NULL ); } if ( rc == LDAP_SERVER_DOWN ) break; } exit( EXIT_SUCCESS ); }
static int dds_cfgen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; dds_info_t *di = on->on_bi.bi_private; int rc = 0; unsigned long t; if ( c->op == SLAP_CONFIG_EMIT ) { char buf[ SLAP_TEXT_BUFLEN ]; struct berval bv; switch( c->type ) { case DDS_STATE: c->value_int = !DDS_OFF( di ); break; case DDS_MAXTTL: lutil_unparse_time( buf, sizeof( buf ), di->di_max_ttl ); ber_str2bv( buf, 0, 0, &bv ); value_add_one( &c->rvalue_vals, &bv ); break; case DDS_MINTTL: if ( di->di_min_ttl ) { lutil_unparse_time( buf, sizeof( buf ), di->di_min_ttl ); ber_str2bv( buf, 0, 0, &bv ); value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } break; case DDS_DEFAULTTTL: if ( di->di_default_ttl ) { lutil_unparse_time( buf, sizeof( buf ), di->di_default_ttl ); ber_str2bv( buf, 0, 0, &bv ); value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } break; case DDS_INTERVAL: if ( di->di_interval ) { lutil_unparse_time( buf, sizeof( buf ), di->di_interval ); ber_str2bv( buf, 0, 0, &bv ); value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } break; case DDS_TOLERANCE: if ( di->di_tolerance ) { lutil_unparse_time( buf, sizeof( buf ), di->di_tolerance ); ber_str2bv( buf, 0, 0, &bv ); value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } break; case DDS_MAXDYNAMICOBJS: if ( di->di_max_dynamicObjects > 0 ) { c->value_int = di->di_max_dynamicObjects; } else { rc = 1; } break; default: rc = 1; break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { switch( c->type ) { case DDS_STATE: di->di_flags &= ~DDS_FOFF; break; case DDS_MAXTTL: di->di_min_ttl = DDS_RF2589_DEFAULT_TTL; break; case DDS_MINTTL: di->di_min_ttl = 0; break; case DDS_DEFAULTTTL: di->di_default_ttl = 0; break; case DDS_INTERVAL: di->di_interval = 0; break; case DDS_TOLERANCE: di->di_tolerance = 0; break; case DDS_MAXDYNAMICOBJS: di->di_max_dynamicObjects = 0; break; default: rc = 1; break; } return rc; } switch ( c->type ) { case DDS_STATE: if ( c->value_int ) { di->di_flags &= ~DDS_FOFF; } else { di->di_flags |= DDS_FOFF; } break; case DDS_MAXTTL: if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) { snprintf( c->cr_msg, sizeof( c->cr_msg), "DDS unable to parse dds-max-ttl \"%s\"", c->argv[ 1 ] ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } if ( t < DDS_RF2589_DEFAULT_TTL || t > DDS_RF2589_MAX_TTL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "DDS invalid dds-max-ttl=%lu; must be between %d and %d", t, DDS_RF2589_DEFAULT_TTL, DDS_RF2589_MAX_TTL ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } di->di_max_ttl = (time_t)t; break; case DDS_MINTTL: if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) { snprintf( c->cr_msg, sizeof( c->cr_msg), "DDS unable to parse dds-min-ttl \"%s\"", c->argv[ 1 ] ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } if ( t > DDS_RF2589_MAX_TTL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "DDS invalid dds-min-ttl=%lu", t ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } if ( t == 0 ) { di->di_min_ttl = DDS_RF2589_DEFAULT_TTL; } else { di->di_min_ttl = (time_t)t; } break; case DDS_DEFAULTTTL: if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) { snprintf( c->cr_msg, sizeof( c->cr_msg), "DDS unable to parse dds-default-ttl \"%s\"", c->argv[ 1 ] ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } if ( t > DDS_RF2589_MAX_TTL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "DDS invalid dds-default-ttl=%lu", t ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } if ( t == 0 ) { di->di_default_ttl = DDS_RF2589_DEFAULT_TTL; } else { di->di_default_ttl = (time_t)t; } break; case DDS_INTERVAL: if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) { snprintf( c->cr_msg, sizeof( c->cr_msg), "DDS unable to parse dds-interval \"%s\"", c->argv[ 1 ] ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } if ( t <= 0 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "DDS invalid dds-interval=%lu", t ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } if ( t < 60 ) { Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_NOTICE, "%s: dds-interval=%lu may be too small.\n", c->log, t ); } di->di_interval = (time_t)t; if ( di->di_expire_task ) { ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); if ( ldap_pvt_runqueue_isrunning( &slapd_rq, di->di_expire_task ) ) { ldap_pvt_runqueue_stoptask( &slapd_rq, di->di_expire_task ); } di->di_expire_task->interval.tv_sec = DDS_INTERVAL( di ); ldap_pvt_runqueue_resched( &slapd_rq, di->di_expire_task, 0 ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } break; case DDS_TOLERANCE: if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) { snprintf( c->cr_msg, sizeof( c->cr_msg), "DDS unable to parse dds-tolerance \"%s\"", c->argv[ 1 ] ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } if ( t > DDS_RF2589_MAX_TTL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "DDS invalid dds-tolerance=%lu", t ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } di->di_tolerance = (time_t)t; break; case DDS_MAXDYNAMICOBJS: if ( c->value_int < 0 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "DDS invalid dds-max-dynamicObjects=%d", c->value_int ); Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, "%s: %s.\n", c->log, c->cr_msg ); return 1; } di->di_max_dynamicObjects = c->value_int; break; default: rc = 1; break; } return rc; }
static int slap_auxprop_store( void *glob_context, sasl_server_params_t *sparams, struct propctx *prctx, const char *user, unsigned ulen) { Operation op = {0}; Opheader oph; SlapReply rs = {REP_RESULT}; int rc, i; unsigned j; Connection *conn = NULL; const struct propval *pr; Modifications *modlist = NULL, **modtail = &modlist, *mod; slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; char textbuf[SLAP_TEXT_BUFLEN]; const char *text; size_t textlen = sizeof(textbuf); /* just checking if we are enabled */ if (!prctx) return SASL_OK; if (!sparams || !user) return SASL_BADPARAM; pr = sparams->utils->prop_get( sparams->propctx ); /* Find our DN and conn first */ for( i = 0; pr[i].name; i++ ) { if ( pr[i].name[0] == '*' ) { if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_CONN] ) ) { if ( pr[i].values && pr[i].values[0] ) AC_MEMCPY( &conn, pr[i].values[0], sizeof( conn ) ); continue; } if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_AUTHCLEN] )) { if ( pr[i].values && pr[i].values[0] ) AC_MEMCPY( &op.o_req_ndn.bv_len, pr[i].values[0], sizeof( op.o_req_ndn.bv_len ) ); } else if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) { if ( pr[i].values ) op.o_req_ndn.bv_val = (char *)pr[i].values[0]; } } } if (!conn || !op.o_req_ndn.bv_val) return SASL_BADPARAM; op.o_bd = select_backend( &op.o_req_ndn, 1 ); if ( !op.o_bd || !op.o_bd->be_modify ) return SASL_FAIL; pr = sparams->utils->prop_get( prctx ); if (!pr) return SASL_BADPARAM; for (i=0; pr[i].name; i++); if (!i) return SASL_BADPARAM; for (i=0; pr[i].name; i++) { mod = (Modifications *)ch_malloc( sizeof(Modifications) ); mod->sml_op = LDAP_MOD_REPLACE; mod->sml_flags = 0; ber_str2bv( pr[i].name, 0, 0, &mod->sml_type ); mod->sml_numvals = pr[i].nvalues; mod->sml_values = (struct berval *)ch_malloc( (pr[i].nvalues + 1) * sizeof(struct berval)); for (j=0; j<pr[i].nvalues; j++) { ber_str2bv( pr[i].values[j], 0, 1, &mod->sml_values[j]); } BER_BVZERO( &mod->sml_values[j] ); mod->sml_nvalues = NULL; mod->sml_desc = NULL; *modtail = mod; modtail = &mod->sml_next; } *modtail = NULL; rc = slap_mods_check( &op, modlist, &text, textbuf, textlen, NULL ); if ( rc == LDAP_SUCCESS ) { rc = slap_mods_no_user_mod_check( &op, modlist, &text, textbuf, textlen ); if ( rc == LDAP_SUCCESS ) { if ( conn->c_sasl_bindop ) { op.o_hdr = conn->c_sasl_bindop->o_hdr; } else { op.o_hdr = &oph; memset( &oph, 0, sizeof(oph) ); operation_fake_init( conn, &op, ldap_pvt_thread_pool_context(), 0 ); } op.o_tag = LDAP_REQ_MODIFY; op.o_ndn = op.o_req_ndn; op.o_callback = &cb; slap_op_time( &op.o_time, &op.o_tincr ); op.o_do_not_cache = 1; op.o_is_auth_check = 1; op.o_req_dn = op.o_req_ndn; op.orm_modlist = modlist; rc = op.o_bd->be_modify( &op, &rs ); } } slap_mods_free( modlist, 1 ); return rc != LDAP_SUCCESS ? SASL_FAIL : SASL_OK; }
int frontend_init( void ) { /* data */ frontendDB = &slap_frontendDB; frontendDB->bd_self = frontendDB; /* ACLs */ frontendDB->be_dfltaccess = ACL_READ; /* limits */ frontendDB->be_def_limit.lms_t_soft = SLAPD_DEFAULT_TIMELIMIT; /* backward compatible limits */ frontendDB->be_def_limit.lms_t_hard = 0; frontendDB->be_def_limit.lms_s_soft = SLAPD_DEFAULT_SIZELIMIT; /* backward compatible limits */ frontendDB->be_def_limit.lms_s_hard = 0; frontendDB->be_def_limit.lms_s_unchecked = -1; /* no limit on unchecked size */ frontendDB->be_def_limit.lms_s_pr = 0; /* page limit */ frontendDB->be_def_limit.lms_s_pr_hide = 0; /* don't hide number of entries left */ frontendDB->be_def_limit.lms_s_pr_total = 0; /* number of total entries returned by pagedResults equal to hard limit */ ldap_pvt_thread_mutex_init( &frontendDB->be_pcl_mutex ); /* suffix */ frontendDB->be_suffix = ch_calloc( 2, sizeof( struct berval ) ); ber_str2bv( "", 0, 1, &frontendDB->be_suffix[0] ); BER_BVZERO( &frontendDB->be_suffix[1] ); frontendDB->be_nsuffix = ch_calloc( 2, sizeof( struct berval ) ); ber_str2bv( "", 0, 1, &frontendDB->be_nsuffix[0] ); BER_BVZERO( &frontendDB->be_nsuffix[1] ); /* info */ frontendDB->bd_info = &slap_frontendInfo; SLAP_BFLAGS(frontendDB) |= SLAP_BFLAG_FRONTEND; /* name */ frontendDB->bd_info->bi_type = "frontend"; /* known controls */ { int i; frontendDB->bd_info->bi_controls = slap_known_controls; for ( i = 0; slap_known_controls[ i ]; i++ ) { int cid; if ( slap_find_control_id( slap_known_controls[ i ], &cid ) == LDAP_CONTROL_NOT_FOUND ) { assert( 0 ); return -1; } frontendDB->bd_info->bi_ctrls[ cid ] = 1; frontendDB->be_ctrls[ cid ] = 1; } } /* calls */ frontendDB->bd_info->bi_op_abandon = fe_op_abandon; frontendDB->bd_info->bi_op_add = fe_op_add; frontendDB->bd_info->bi_op_bind = fe_op_bind; frontendDB->bd_info->bi_op_compare = fe_op_compare; frontendDB->bd_info->bi_op_delete = fe_op_delete; frontendDB->bd_info->bi_op_modify = fe_op_modify; frontendDB->bd_info->bi_op_modrdn = fe_op_modrdn; frontendDB->bd_info->bi_op_search = fe_op_search; frontendDB->bd_info->bi_extended = fe_extended; frontendDB->bd_info->bi_operational = fe_aux_operational; frontendDB->bd_info->bi_entry_get_rw = fe_entry_get_rw; frontendDB->bd_info->bi_entry_release_rw = fe_entry_release_rw; frontendDB->bd_info->bi_access_allowed = fe_access_allowed; frontendDB->bd_info->bi_acl_group = fe_acl_group; frontendDB->bd_info->bi_acl_attribute = fe_acl_attribute; #if 0 /* FIXME: is this too early? */ return backend_startup_one( frontendDB ); #endif return 0; }
static void * slapd_rw_config( const char *fname, int lineno, int argc, char **argv ) { slapd_map_data *ret = NULL; LDAPURLDesc *lud = NULL; char *uri; AttributeDescription *ad = NULL; int rc, flen = 0; struct berval dn, ndn; if ( argc != 1 ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] slapd map needs URI\n", fname, lineno, 0 ); return NULL; } uri = argv[0]; if ( strncasecmp( uri, "uri=", STRLENOF( "uri=" ) ) == 0 ) { uri += STRLENOF( "uri=" ); } if ( ldap_url_parse( uri, &lud ) != LDAP_URL_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] illegal URI '%s'\n", fname, lineno, uri ); return NULL; } if ( strcasecmp( lud->lud_scheme, "ldap" )) { Debug( LDAP_DEBUG_ANY, "[%s:%d] illegal URI scheme '%s'\n", fname, lineno, lud->lud_scheme ); goto done; } if (( lud->lud_host && lud->lud_host[0] ) || lud->lud_exts || !lud->lud_dn ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] illegal URI '%s'\n", fname, lineno, uri ); goto done; } if ( lud->lud_attrs ) { if ( lud->lud_attrs[1] ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] only one attribute allowed in URI\n", fname, lineno, 0 ); goto done; } if ( strcasecmp( lud->lud_attrs[0], "dn" ) && strcasecmp( lud->lud_attrs[0], "entryDN" )) { const char *text; rc = slap_str2ad( lud->lud_attrs[0], &ad, &text ); if ( rc ) goto done; } } ber_str2bv( lud->lud_dn, 0, 0, &dn ); if ( dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL )) goto done; if ( lud->lud_filter ) { flen = strlen( lud->lud_filter ) + 1; } ret = ch_malloc( sizeof( slapd_map_data ) + flen ); ret->base = ndn; if ( flen ) { ret->filter.bv_val = (char *)(ret+1); ret->filter.bv_len = flen - 1; strcpy( ret->filter.bv_val, lud->lud_filter ); } else { BER_BVZERO( &ret->filter ); } ret->scope = lud->lud_scope; if ( ad ) { ret->attrs[0].an_name = ad->ad_cname; } else { BER_BVZERO( &ret->attrs[0].an_name ); } ret->attrs[0].an_desc = ad; BER_BVZERO( &ret->attrs[1].an_name ); done: ldap_free_urldesc( lud ); return ret; }
static int dl_cfgen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; dynlist_info_t *dli = (dynlist_info_t *)on->on_bi.bi_private; int rc = 0, i; if ( c->op == SLAP_CONFIG_EMIT ) { switch( c->type ) { case DL_ATTRSET: for ( i = 0; dli; i++, dli = dli->dli_next ) { struct berval bv; char *ptr = c->cr_msg; dynlist_map_t *dlm; assert( dli->dli_oc != NULL ); assert( dli->dli_ad != NULL ); /* FIXME: check buffer overflow! */ ptr += snprintf( c->cr_msg, sizeof( c->cr_msg ), SLAP_X_ORDERED_FMT "%s", i, dli->dli_oc->soc_cname.bv_val ); if ( !BER_BVISNULL( &dli->dli_uri ) ) { *ptr++ = ' '; *ptr++ = '"'; ptr = lutil_strncopy( ptr, dli->dli_uri.bv_val, dli->dli_uri.bv_len ); *ptr++ = '"'; } *ptr++ = ' '; ptr = lutil_strncopy( ptr, dli->dli_ad->ad_cname.bv_val, dli->dli_ad->ad_cname.bv_len ); for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) { ptr[ 0 ] = ' '; ptr++; if ( dlm->dlm_mapped_ad ) { ptr = lutil_strcopy( ptr, dlm->dlm_mapped_ad->ad_cname.bv_val ); ptr[ 0 ] = ':'; ptr++; } ptr = lutil_strcopy( ptr, dlm->dlm_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 DL_ATTRPAIR_COMPAT: case DL_ATTRPAIR: rc = 1; break; default: rc = 1; break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { switch( c->type ) { case DL_ATTRSET: if ( c->valx < 0 ) { dynlist_info_t *dli_next; for ( dli_next = dli; dli_next; dli = dli_next ) { dynlist_map_t *dlm = dli->dli_dlm; dynlist_map_t *dlm_next; dli_next = dli->dli_next; if ( !BER_BVISNULL( &dli->dli_uri ) ) { ch_free( dli->dli_uri.bv_val ); } if ( dli->dli_lud != NULL ) { ldap_free_urldesc( dli->dli_lud ); } if ( !BER_BVISNULL( &dli->dli_uri_nbase ) ) { ber_memfree( dli->dli_uri_nbase.bv_val ); } if ( dli->dli_uri_filter != NULL ) { filter_free( dli->dli_uri_filter ); } ch_free( dli->dli_default_filter.bv_val ); while ( dlm != NULL ) { dlm_next = dlm->dlm_next; ch_free( dlm ); dlm = dlm_next; } ch_free( dli ); } on->on_bi.bi_private = NULL; } else { dynlist_info_t **dlip; dynlist_map_t *dlm; dynlist_map_t *dlm_next; for ( i = 0, dlip = (dynlist_info_t **)&on->on_bi.bi_private; i < c->valx; i++ ) { if ( *dlip == NULL ) { return 1; } dlip = &(*dlip)->dli_next; } dli = *dlip; *dlip = dli->dli_next; if ( !BER_BVISNULL( &dli->dli_uri ) ) { ch_free( dli->dli_uri.bv_val ); } if ( dli->dli_lud != NULL ) { ldap_free_urldesc( dli->dli_lud ); } if ( !BER_BVISNULL( &dli->dli_uri_nbase ) ) { ber_memfree( dli->dli_uri_nbase.bv_val ); } if ( dli->dli_uri_filter != NULL ) { filter_free( dli->dli_uri_filter ); } ch_free( dli->dli_default_filter.bv_val ); dlm = dli->dli_dlm; while ( dlm != NULL ) { dlm_next = dlm->dlm_next; ch_free( dlm ); dlm = dlm_next; } ch_free( dli ); dli = (dynlist_info_t *)on->on_bi.bi_private; } break; case DL_ATTRPAIR_COMPAT: case DL_ATTRPAIR: rc = 1; break; default: rc = 1; break; } return rc; } switch( c->type ) { case DL_ATTRSET: { dynlist_info_t **dlip, *dli_next = NULL; ObjectClass *oc = NULL; AttributeDescription *ad = NULL; int attridx = 2; LDAPURLDesc *lud = NULL; struct berval nbase = BER_BVNULL; Filter *filter = NULL; struct berval uri = BER_BVNULL; dynlist_map_t *dlm = NULL; const char *text; oc = oc_find( c->argv[ 1 ] ); if ( oc == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "unable to find ObjectClass \"%s\"", c->argv[ 1 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } if ( strncasecmp( c->argv[ attridx ], "ldap://", STRLENOF("ldap://") ) == 0 ) { if ( ldap_url_parse( c->argv[ attridx ], &lud ) != LDAP_URL_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "unable to parse URI \"%s\"", c->argv[ attridx ] ); rc = 1; goto done_uri; } if ( lud->lud_host != NULL ) { if ( lud->lud_host[0] == '\0' ) { ch_free( lud->lud_host ); lud->lud_host = NULL; } else { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "host not allowed in URI \"%s\"", c->argv[ attridx ] ); rc = 1; goto done_uri; } } if ( lud->lud_attrs != NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "attrs not allowed in URI \"%s\"", c->argv[ attridx ] ); rc = 1; goto done_uri; } if ( lud->lud_exts != NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "extensions not allowed in URI \"%s\"", c->argv[ attridx ] ); rc = 1; goto done_uri; } if ( lud->lud_dn != NULL && lud->lud_dn[ 0 ] != '\0' ) { struct berval dn; ber_str2bv( lud->lud_dn, 0, 0, &dn ); rc = dnNormalize( 0, NULL, NULL, &dn, &nbase, NULL ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "DN normalization failed in URI \"%s\"", c->argv[ attridx ] ); goto done_uri; } } if ( lud->lud_filter != NULL && lud->lud_filter[ 0 ] != '\0' ) { filter = str2filter( lud->lud_filter ); if ( filter == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "filter parsing failed in URI \"%s\"", c->argv[ attridx ] ); rc = 1; goto done_uri; } } ber_str2bv( c->argv[ attridx ], 0, 1, &uri ); done_uri:; if ( rc ) { if ( lud ) { ldap_free_urldesc( lud ); } if ( !BER_BVISNULL( &nbase ) ) { ber_memfree( nbase.bv_val ); } if ( filter != NULL ) { filter_free( filter ); } Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return rc; } attridx++; } rc = slap_str2ad( c->argv[ attridx ], &ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "unable to find AttributeDescription \"%s\"", c->argv[ attridx ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "AttributeDescription \"%s\" " "must be a subtype of \"labeledURI\"", c->argv[ attridx ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } attridx++; for ( i = attridx; i < c->argc; i++ ) { char *arg; char *cp; AttributeDescription *member_ad = NULL; AttributeDescription *mapped_ad = NULL; dynlist_map_t *dlmp; dynlist_map_t *dlml; /* * If no mapped attribute is given, dn is used * for backward compatibility. */ arg = c->argv[i]; if ( ( cp = strchr( arg, ':' ) ) != NULL ) { struct berval bv; ber_str2bv( arg, cp - arg, 0, &bv ); rc = slap_bv2ad( &bv, &mapped_ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "unable to find mapped AttributeDescription #%d \"%s\"\n", i - 3, c->argv[ i ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } arg = cp + 1; } rc = slap_str2ad( arg, &member_ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "unable to find AttributeDescription #%d \"%s\"\n", i - 3, c->argv[ i ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } dlmp = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) ); if ( dlm == NULL ) { dlm = dlmp; dlml = NULL; } dlmp->dlm_member_ad = member_ad; dlmp->dlm_mapped_ad = mapped_ad; dlmp->dlm_next = NULL; if ( dlml != NULL ) dlml->dlm_next = dlmp; dlml = dlmp; } if ( c->valx > 0 ) { int i; for ( i = 0, dlip = (dynlist_info_t **)&on->on_bi.bi_private; i < c->valx; i++ ) { if ( *dlip == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "invalid index {%d}\n", c->valx ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } dlip = &(*dlip)->dli_next; } dli_next = *dlip; } else { for ( dlip = (dynlist_info_t **)&on->on_bi.bi_private; *dlip; dlip = &(*dlip)->dli_next ) /* goto last */; } *dlip = (dynlist_info_t *)ch_calloc( 1, sizeof( dynlist_info_t ) ); (*dlip)->dli_oc = oc; (*dlip)->dli_ad = ad; (*dlip)->dli_dlm = dlm; (*dlip)->dli_next = dli_next; (*dlip)->dli_lud = lud; (*dlip)->dli_uri_nbase = nbase; (*dlip)->dli_uri_filter = filter; (*dlip)->dli_uri = uri; rc = dynlist_build_def_filter( *dlip ); } break; case DL_ATTRPAIR_COMPAT: snprintf( c->cr_msg, sizeof( c->cr_msg ), "warning: \"attrpair\" only supported for limited " "backward compatibility with overlay \"dyngroup\"" ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); /* fallthru */ case DL_ATTRPAIR: { dynlist_info_t **dlip; ObjectClass *oc = NULL; AttributeDescription *ad = NULL, *member_ad = NULL; const char *text; oc = oc_find( "groupOfURLs" ); if ( oc == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "\"dynlist-attrpair <member-ad> <URL-ad>\": " "unable to find default ObjectClass \"groupOfURLs\"" ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } rc = slap_str2ad( c->argv[ 1 ], &member_ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "\"dynlist-attrpair <member-ad> <URL-ad>\": " "unable to find AttributeDescription \"%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 ], &ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "\"dynlist-attrpair <member-ad> <URL-ad>\": " "unable to find AttributeDescription \"%s\"\n", c->argv[ 2 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "AttributeDescription \"%s\" " "must be a subtype of \"labeledURI\"", c->argv[ 2 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } for ( dlip = (dynlist_info_t **)&on->on_bi.bi_private; *dlip; dlip = &(*dlip)->dli_next ) { /* * The same URL attribute / member attribute pair * cannot be repeated, but we enforce this only * when the member attribute is unique. Performing * the check for multiple values would require * sorting and comparing the lists, which is left * as a future improvement */ if ( (*dlip)->dli_ad == ad && (*dlip)->dli_dlm->dlm_next == NULL && member_ad == (*dlip)->dli_dlm->dlm_member_ad ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "\"dynlist-attrpair <member-ad> <URL-ad>\": " "URL attributeDescription \"%s\" already mapped.\n", ad->ad_cname.bv_val ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); #if 0 /* make it a warning... */ return 1; #endif } } *dlip = (dynlist_info_t *)ch_calloc( 1, sizeof( dynlist_info_t ) ); (*dlip)->dli_oc = oc; (*dlip)->dli_ad = ad; (*dlip)->dli_dlm = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) ); (*dlip)->dli_dlm->dlm_member_ad = member_ad; (*dlip)->dli_dlm->dlm_mapped_ad = NULL; rc = dynlist_build_def_filter( *dlip ); } break; default: rc = 1; break; } return rc; }
int dnssrv_back_search( Operation *op, SlapReply *rs ) { int i; int rc; char *domain = NULL; char *hostlist = NULL; char **hosts = NULL; char *refdn; struct berval nrefdn = BER_BVNULL; BerVarray urls = NULL; int manageDSAit; rs->sr_ref = NULL; if ( BER_BVISEMPTY( &op->o_req_ndn ) ) { /* FIXME: need some means to determine whether the database * is a glue instance; if we got here with empty DN, then * we passed this same test in dnssrv_back_referrals() */ if ( !SLAP_GLUE_INSTANCE( op->o_bd ) ) { rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed"; } else { rs->sr_err = LDAP_SUCCESS; } goto done; } manageDSAit = get_manageDSAit( op ); /* * FIXME: we may return a referral if manageDSAit is not set */ if ( !manageDSAit ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "manageDSAit must be set" ); goto done; } if( ldap_dn2domain( op->o_req_dn.bv_val, &domain ) || domain == NULL ) { rs->sr_err = LDAP_REFERRAL; rs->sr_ref = default_referral; send_ldap_result( op, rs ); rs->sr_ref = NULL; goto done; } Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n", op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", domain, 0 ); if( ( rc = ldap_domain2hostlist( domain, &hostlist ) ) ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n", rc, 0, 0 ); send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT, "no DNS SRV RR available for DN" ); goto done; } hosts = ldap_str2charray( hostlist, " " ); if( hosts == NULL ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 ); send_ldap_error( op, rs, LDAP_OTHER, "problem processing DNS SRV records for DN" ); goto done; } for( i=0; hosts[i] != NULL; i++) { struct berval url; url.bv_len = STRLENOF( "ldap://" ) + strlen(hosts[i]); url.bv_val = ch_malloc( url.bv_len + 1 ); strcpy( url.bv_val, "ldap://" ); strcpy( &url.bv_val[STRLENOF( "ldap://" )], hosts[i] ); if( ber_bvarray_add( &urls, &url ) < 0 ) { free( url.bv_val ); send_ldap_error( op, rs, LDAP_OTHER, "problem processing DNS SRV records for DN" ); goto done; } } Statslog( LDAP_DEBUG_STATS, "%s DNSSRV p=%d dn=\"%s\" url=\"%s\"\n", op->o_log_prefix, op->o_protocol, op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", urls[0].bv_val, 0 ); Debug( LDAP_DEBUG_TRACE, "DNSSRV: ManageDSAit scope=%d dn=\"%s\" -> url=\"%s\"\n", op->oq_search.rs_scope, op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", urls[0].bv_val ); rc = ldap_domain2dn(domain, &refdn); if( rc != LDAP_SUCCESS ) { send_ldap_error( op, rs, LDAP_OTHER, "DNS SRV problem processing manageDSAit control" ); goto done; } else { struct berval bv; bv.bv_val = refdn; bv.bv_len = strlen( refdn ); rc = dnNormalize( 0, NULL, NULL, &bv, &nrefdn, op->o_tmpmemctx ); if( rc != LDAP_SUCCESS ) { send_ldap_error( op, rs, LDAP_OTHER, "DNS SRV problem processing manageDSAit control" ); goto done; } } if( !dn_match( &nrefdn, &op->o_req_ndn ) ) { /* requested dn is subordinate */ Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" subordinate to refdn=\"%s\"\n", op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", refdn == NULL ? "" : refdn, NULL ); rs->sr_matched = refdn; rs->sr_err = LDAP_NO_SUCH_OBJECT; send_ldap_result( op, rs ); rs->sr_matched = NULL; } else if ( op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL ) { send_ldap_error( op, rs, LDAP_SUCCESS, NULL ); } else { Entry e = { 0 }; AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass; AttributeDescription *ad_ref = slap_schema.si_ad_ref; e.e_name.bv_val = ch_strdup( op->o_req_dn.bv_val ); e.e_name.bv_len = op->o_req_dn.bv_len; e.e_nname.bv_val = ch_strdup( op->o_req_ndn.bv_val ); e.e_nname.bv_len = op->o_req_ndn.bv_len; e.e_attrs = NULL; e.e_private = NULL; attr_merge_one( &e, ad_objectClass, &slap_schema.si_oc_referral->soc_cname, NULL ); attr_merge_one( &e, ad_objectClass, &slap_schema.si_oc_extensibleObject->soc_cname, NULL ); if ( ad_dc ) { char *p; struct berval bv; bv.bv_val = domain; p = strchr( bv.bv_val, '.' ); if ( p == bv.bv_val ) { bv.bv_len = 1; } else if ( p != NULL ) { bv.bv_len = p - bv.bv_val; } else { bv.bv_len = strlen( bv.bv_val ); } attr_merge_normalize_one( &e, ad_dc, &bv, NULL ); } if ( ad_associatedDomain ) { struct berval bv; ber_str2bv( domain, 0, 0, &bv ); attr_merge_normalize_one( &e, ad_associatedDomain, &bv, NULL ); } attr_merge_normalize_one( &e, ad_ref, urls, NULL ); rc = test_filter( op, &e, op->oq_search.rs_filter ); if( rc == LDAP_COMPARE_TRUE ) { rs->sr_entry = &e; rs->sr_attrs = op->oq_search.rs_attrs; rs->sr_flags = REP_ENTRY_MODIFIABLE; send_search_entry( op, rs ); rs->sr_entry = NULL; rs->sr_attrs = NULL; } entry_clean( &e ); rs->sr_err = LDAP_SUCCESS; send_ldap_result( op, rs ); } if ( refdn ) free( refdn ); if ( nrefdn.bv_val ) free( nrefdn.bv_val ); done: if( domain != NULL ) ch_free( domain ); if( hostlist != NULL ) ch_free( hostlist ); if( hosts != NULL ) ldap_charray_free( hosts ); if( urls != NULL ) ber_bvarray_free( urls ); return 0; }
static int dynlist_db_config( BackendDB *be, const char *fname, int lineno, int argc, char **argv ) { slap_overinst *on = (slap_overinst *)be->bd_info; int rc = 0; if ( strcasecmp( argv[0], "dynlist-attrset" ) == 0 ) { dynlist_info_t **dlip; ObjectClass *oc; AttributeDescription *ad = NULL, *member_ad = NULL; dynlist_map_t *dlm = NULL; const char *text; if ( argc < 3 ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE "invalid arg number #%d.\n", fname, lineno, argc ); return 1; } oc = oc_find( argv[1] ); if ( oc == NULL ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE "unable to find ObjectClass \"%s\"\n", fname, lineno, argv[ 1 ] ); return 1; } rc = slap_str2ad( argv[2], &ad, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE "unable to find AttributeDescription \"%s\"\n", fname, lineno, argv[2] ); return 1; } if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE "AttributeDescription \"%s\" " "must be a subtype of \"labeledURI\"\n", fname, lineno, argv[2] ); return 1; } for ( i = 3; i < argc; i++ ) { char *arg; char *cp; AttributeDescription *member_ad = NULL; AttributeDescription *mapped_ad = NULL; dynlist_map_t *dlmp; dynlist_map_t *dlml; /* * If no mapped attribute is given, dn is used * for backward compatibility. */ arg = argv[i]; if ( cp = strchr( arg, (int)':' ) != NULL ) { struct berval bv; ber_str2bv( arg, cp - arg, 0, &bv ); rc = slap_bv2ad( &bv, &mapped_ad, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE "unable to find mapped AttributeDescription \"%s\"\n", fname, lineno, arg ); return 1; } arg = cp + 1; } rc = slap_str2ad( arg, &member_ad, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE "unable to find AttributeDescription \"%s\"\n", fname, lineno, arg ); return 1; } dlmp = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) ); if ( dlm == NULL ) { dlm = dlmp; dlml = NULL; } dlmp->dlm_member_ad = member_ad; dlmp->dlm_mapped_ad = mapped_ad; dlmp->dlm_next = NULL; if ( dlml != NULL ) dlml->dlm_next = dlmp; dlml = dlmp; } for ( dlip = (dynlist_info_t **)&on->on_bi.bi_private; *dlip; dlip = &(*dlip)->dli_next ) { /* * The same URL attribute / member attribute pair * cannot be repeated, but we enforce this only * when the member attribute is unique. Performing * the check for multiple values would require * sorting and comparing the lists, which is left * as a future improvement */ if ( (*dlip)->dli_ad == ad && (*dlip)->dli_dlm->dlm_next == NULL && dlm->dlm_next == NULL && dlm->dlm_member_ad == (*dlip)->dli_dlm->dlm_member_ad && dlm->dlm_mapped_ad == (*dlip)->dli_dlm->dlm_mapped_ad ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE "URL attributeDescription \"%s\" already mapped.\n", fname, lineno, ad->ad_cname.bv_val ); #if 0 /* make it a warning... */ return 1; #endif } } *dlip = (dynlist_info_t *)ch_calloc( 1, sizeof( dynlist_info_t ) ); (*dlip)->dli_oc = oc; (*dlip)->dli_ad = ad; (*dlip)->dli_dlm = dlm; if ( dynlist_build_def_filter( *dlip ) ) { dynlist_map_t *dlm = (*dlip)->ldi_dlm; dynlist_map_t *dlm_next; while ( dlm != NULL ) { dlm_next = dlm->dlm_next; ch_free( dlm ); dlm = dlm_next; } ch_free( *dlip ); *dlip = NULL; return 1; } /* allow dyngroup syntax */ } else if ( strcasecmp( argv[0], "dynlist-attrpair" ) == 0 ) { dynlist_info_t **dlip; ObjectClass *oc; AttributeDescription *ad = NULL, *member_ad = NULL; const char *text; if ( argc != 3 ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " "\"dynlist-attrpair <member-ad> <URL-ad>\": " "invalid arg number #%d.\n", fname, lineno, argc ); return 1; } oc = oc_find( "groupOfURLs" ); if ( oc == NULL ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " "\"dynlist-attrpair <member-ad> <URL-ad>\": " "unable to find default ObjectClass \"groupOfURLs\"\n", fname, lineno, 0 ); return 1; } rc = slap_str2ad( argv[1], &member_ad, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " "\"dynlist-attrpair <member-ad> <URL-ad>\": " "unable to find AttributeDescription \"%s\"\n", fname, lineno, argv[1] ); return 1; } rc = slap_str2ad( argv[2], &ad, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " "\"dynlist-attrpair <member-ad> <URL-ad>\": " "unable to find AttributeDescription \"%s\"\n", fname, lineno, argv[2] ); return 1; } if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " "\"dynlist-attrpair <member-ad> <URL-ad>\": " "AttributeDescription \"%s\" " "must be a subtype of \"labeledURI\"\n", fname, lineno, argv[2] ); return 1; } for ( dlip = (dynlist_info_t **)&on->on_bi.bi_private; *dlip; dlip = &(*dlip)->dli_next ) { /* * The same URL attribute / member attribute pair * cannot be repeated, but we enforce this only * when the member attribute is unique. Performing * the check for multiple values would require * sorting and comparing the lists, which is left * as a future improvement */ if ( (*dlip)->dli_ad == ad && (*dlip)->dli_dlm->dlm_next == NULL && member_ad == (*dlip)->dli_dlm->dlm_member_ad ) { Debug( LDAP_DEBUG_ANY, "%s: line %d: " "\"dynlist-attrpair <member-ad> <URL-ad>\": " "URL attributeDescription \"%s\" already mapped.\n", fname, lineno, ad->ad_cname.bv_val ); #if 0 /* make it a warning... */ return 1; #endif } } *dlip = (dynlist_info_t *)ch_calloc( 1, sizeof( dynlist_info_t ) ); (*dlip)->dli_oc = oc; (*dlip)->dli_ad = ad; (*dlip)->dli_dlm = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) ); (*dlip)->dli_dlm->dlm_member_ad = member_ad; (*dlip)->dli_dlm->dlm_mapped_ad = NULL; if ( dynlist_build_def_filter( *dlip ) ) { ch_free( (*dlip)->dli_dlm ); ch_free( *dlip ); *dlip = NULL; return 1; } } else { rc = SLAP_CONF_UNKNOWN; } return rc; }
static int constraint_cf_gen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)(c->bi); constraint *cn = on->on_bi.bi_private, *cp; struct berval bv; int i, rc = 0; constraint ap = { NULL }; const char *text = NULL; switch ( c->op ) { case SLAP_CONFIG_EMIT: switch (c->type) { case CONSTRAINT_ATTRIBUTE: for (cp=cn; cp; cp=cp->ap_next) { char *s; char *tstr = NULL; int quotes = 0, numeric = 0; int j; size_t val = 0; char val_buf[SLAP_TEXT_BUFLEN] = { '\0' }; bv.bv_len = STRLENOF(" "); for (j = 0; cp->ap[j]; j++) { bv.bv_len += cp->ap[j]->ad_cname.bv_len; } /* room for commas */ bv.bv_len += j - 1; switch (cp->type) { case CONSTRAINT_COUNT: tstr = COUNT_STR; val = cp->count; numeric = 1; break; case CONSTRAINT_SIZE: tstr = SIZE_STR; val = cp->size; numeric = 1; break; case CONSTRAINT_REGEX: tstr = REGEX_STR; quotes = 1; break; case CONSTRAINT_SET: tstr = SET_STR; quotes = 1; break; case CONSTRAINT_URI: tstr = URI_STR; quotes = 1; break; default: abort(); } bv.bv_len += strlen(tstr); bv.bv_len += cp->val.bv_len + 2*quotes; if (cp->restrict_lud != NULL) { bv.bv_len += cp->restrict_val.bv_len + STRLENOF(" restrict=\"\""); } if (numeric) { int len = snprintf(val_buf, sizeof(val_buf), "%zu", val); if (len <= 0) { /* error */ return -1; } bv.bv_len += len; } s = bv.bv_val = ch_malloc(bv.bv_len + 1); s = lutil_strncopy( s, cp->ap[0]->ad_cname.bv_val, cp->ap[0]->ad_cname.bv_len ); for (j = 1; cp->ap[j]; j++) { *s++ = ','; s = lutil_strncopy( s, cp->ap[j]->ad_cname.bv_val, cp->ap[j]->ad_cname.bv_len ); } *s++ = ' '; s = lutil_strcopy( s, tstr ); *s++ = ' '; if (numeric) { s = lutil_strcopy( s, val_buf ); } else { if ( quotes ) *s++ = '"'; s = lutil_strncopy( s, cp->val.bv_val, cp->val.bv_len ); if ( quotes ) *s++ = '"'; } if (cp->restrict_lud != NULL) { s = lutil_strcopy( s, " restrict=\"" ); s = lutil_strncopy( s, cp->restrict_val.bv_val, cp->restrict_val.bv_len ); *s++ = '"'; } *s = '\0'; rc = value_add_one( &c->rvalue_vals, &bv ); if (rc == LDAP_SUCCESS) rc = value_add_one( &c->rvalue_nvals, &bv ); ch_free(bv.bv_val); if (rc) return rc; } break; default: abort(); break; } break; case LDAP_MOD_DELETE: switch (c->type) { case CONSTRAINT_ATTRIBUTE: if (!cn) break; /* nothing to do */ if (c->valx < 0) { /* zap all constraints */ while (cn) { cp = cn->ap_next; constraint_free( cn, 1 ); cn = cp; } on->on_bi.bi_private = NULL; } else { constraint **cpp; /* zap constraint numbered 'valx' */ for(i=0, cp = cn, cpp = &cn; (cp) && (i<c->valx); i++, cpp = &cp->ap_next, cp = *cpp); if (cp) { /* zap cp, and join cpp to cp->ap_next */ *cpp = cp->ap_next; constraint_free( cp, 1 ); } on->on_bi.bi_private = cn; } break; default: abort(); break; } break; case SLAP_CONFIG_ADD: case LDAP_MOD_ADD: switch (c->type) { case CONSTRAINT_ATTRIBUTE: { int j; char **attrs = ldap_str2charray( c->argv[1], "," ); for ( j = 0; attrs[j]; j++) /* just count */ ; ap.ap = ch_calloc( sizeof(AttributeDescription*), j + 1 ); for ( j = 0; attrs[j]; j++) { if ( slap_str2ad( attrs[j], &ap.ap[j], &text ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s <%s>: %s\n", c->argv[0], attrs[j], text ); rc = ARG_BAD_CONF; goto done; } } if ( strcasecmp( c->argv[2], REGEX_STR ) == 0) { int err; ap.type = CONSTRAINT_REGEX; ap.re = ch_malloc( sizeof(regex_t) ); if ((err = regcomp( ap.re, c->argv[3], REG_EXTENDED )) != 0) { char errmsg[1024]; regerror( err, ap.re, errmsg, sizeof(errmsg) ); ch_free(ap.re); snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Illegal regular expression \"%s\": Error %s", c->argv[0], c->argv[1], c->argv[3], errmsg); ap.re = NULL; rc = ARG_BAD_CONF; goto done; } ber_str2bv( c->argv[3], 0, 1, &ap.val ); } else if ( strcasecmp( c->argv[2], SIZE_STR ) == 0 ) { char *endptr; ap.type = CONSTRAINT_SIZE; ap.size = strtoull(c->argv[3], &endptr, 10); if ( *endptr ) rc = ARG_BAD_CONF; } else if ( strcasecmp( c->argv[2], COUNT_STR ) == 0 ) { char *endptr; ap.type = CONSTRAINT_COUNT; ap.count = strtoull(c->argv[3], &endptr, 10); if ( *endptr ) rc = ARG_BAD_CONF; } else if ( strcasecmp( c->argv[2], URI_STR ) == 0 ) { int err; ap.type = CONSTRAINT_URI; err = ldap_url_parse(c->argv[3], &ap.lud); if ( err != LDAP_URL_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Invalid URI \"%s\"", c->argv[0], c->argv[1], c->argv[3]); rc = ARG_BAD_CONF; goto done; } if (ap.lud->lud_host != NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unsupported hostname in URI \"%s\"", c->argv[0], c->argv[1], c->argv[3]); ldap_free_urldesc(ap.lud); rc = ARG_BAD_CONF; goto done; } for ( i=0; ap.lud->lud_attrs[i]; i++); /* FIXME: This is worthless without at least one attr */ if ( i ) { ap.attrs = ch_malloc( (i+1)*sizeof(AttributeDescription *)); for ( i=0; ap.lud->lud_attrs[i]; i++) { ap.attrs[i] = NULL; if ( slap_str2ad( ap.lud->lud_attrs[i], &ap.attrs[i], &text ) ) { ch_free( ap.attrs ); snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s <%s>: %s\n", c->argv[0], ap.lud->lud_attrs[i], text ); rc = ARG_BAD_CONF; goto done; } } ap.attrs[i] = NULL; } if (ap.lud->lud_dn == NULL) { ap.lud->lud_dn = ch_strdup(""); } else { struct berval dn, ndn; ber_str2bv( ap.lud->lud_dn, 0, 0, &dn ); if (dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) ) { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: URI %s DN normalization failed", c->argv[0], c->argv[1], c->argv[3] ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg ); rc = ARG_BAD_CONF; goto done; } ldap_memfree( ap.lud->lud_dn ); ap.lud->lud_dn = ndn.bv_val; } if (ap.lud->lud_filter == NULL) { ap.lud->lud_filter = ch_strdup("objectClass=*"); } else if ( ap.lud->lud_filter[0] == '(' ) { ber_len_t len = strlen( ap.lud->lud_filter ); if ( ap.lud->lud_filter[len - 1] != ')' ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: invalid URI filter: %s", c->argv[0], c->argv[1], ap.lud->lud_filter ); rc = ARG_BAD_CONF; goto done; } memmove( &ap.lud->lud_filter[0], &ap.lud->lud_filter[1], len - 2 ); ap.lud->lud_filter[len - 2] = '\0'; } ber_str2bv( c->argv[3], 0, 1, &ap.val ); } else if ( strcasecmp( c->argv[2], SET_STR ) == 0 ) { ap.set = 1; ber_str2bv( c->argv[3], 0, 1, &ap.val ); ap.type = CONSTRAINT_SET; } else { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Unknown constraint type: %s", c->argv[0], c->argv[1], c->argv[2] ); rc = ARG_BAD_CONF; goto done; } if ( c->argc > 4 ) { int argidx; for ( argidx = 4; argidx < c->argc; argidx++ ) { if ( strncasecmp( c->argv[argidx], "restrict=", STRLENOF("restrict=") ) == 0 ) { int err; char *arg = c->argv[argidx] + STRLENOF("restrict="); err = ldap_url_parse(arg, &ap.restrict_lud); if ( err != LDAP_URL_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Invalid restrict URI \"%s\"", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } if (ap.restrict_lud->lud_host != NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unsupported hostname in restrict URI \"%s\"", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } if ( ap.restrict_lud->lud_attrs != NULL ) { if ( ap.restrict_lud->lud_attrs[0] != '\0' ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: attrs not allowed in restrict URI %s\n", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } ldap_memvfree((void *)ap.restrict_lud->lud_attrs); ap.restrict_lud->lud_attrs = NULL; } if (ap.restrict_lud->lud_dn != NULL) { if (ap.restrict_lud->lud_dn[0] == '\0') { ldap_memfree(ap.restrict_lud->lud_dn); ap.restrict_lud->lud_dn = NULL; } else { struct berval dn, ndn; int j; ber_str2bv(ap.restrict_lud->lud_dn, 0, 0, &dn); if (dnNormalize(0, NULL, NULL, &dn, &ndn, NULL)) { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI %s DN normalization failed", c->argv[0], c->argv[1], arg ); rc = ARG_BAD_CONF; goto done; } assert(c->be != NULL); if (c->be->be_nsuffix == NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI requires suffix", c->argv[0], c->argv[1] ); rc = ARG_BAD_CONF; goto done; } for ( j = 0; !BER_BVISNULL(&c->be->be_nsuffix[j]); j++) { if (dnIsSuffix(&ndn, &c->be->be_nsuffix[j])) break; } if (BER_BVISNULL(&c->be->be_nsuffix[j])) { /* error */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI DN %s not within database naming context(s)", c->argv[0], c->argv[1], dn.bv_val ); rc = ARG_BAD_CONF; goto done; } ap.restrict_ndn = ndn; } } if (ap.restrict_lud->lud_filter != NULL) { ap.restrict_filter = str2filter(ap.restrict_lud->lud_filter); if (ap.restrict_filter == NULL) { /* error */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI filter %s invalid", c->argv[0], c->argv[1], ap.restrict_lud->lud_filter ); rc = ARG_BAD_CONF; goto done; } } ber_str2bv(c->argv[argidx] + STRLENOF("restrict="), 0, 1, &ap.restrict_val); } else { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unrecognized arg #%d (%s)", c->argv[0], c->argv[1], argidx, c->argv[argidx] ); rc = ARG_BAD_CONF; goto done; } } } done:; if ( rc == LDAP_SUCCESS ) { constraint *a2 = ch_calloc( sizeof(constraint), 1 ); a2->ap_next = on->on_bi.bi_private; a2->ap = ap.ap; a2->type = ap.type; a2->re = ap.re; a2->val = ap.val; a2->lud = ap.lud; a2->set = ap.set; a2->size = ap.size; a2->count = ap.count; if ( a2->lud ) { ber_str2bv(a2->lud->lud_dn, 0, 0, &a2->dn); ber_str2bv(a2->lud->lud_filter, 0, 0, &a2->filter); } a2->attrs = ap.attrs; a2->restrict_lud = ap.restrict_lud; a2->restrict_ndn = ap.restrict_ndn; a2->restrict_filter = ap.restrict_filter; a2->restrict_val = ap.restrict_val; on->on_bi.bi_private = a2; } else { Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg ); constraint_free( &ap, 0 ); } ldap_memvfree((void**)attrs); } break; default: abort(); break; } break; default: abort(); } return rc; }
static int bdb_cf_gen( ConfigArgs *c ) { struct bdb_info *bdb = c->be->be_private; int rc; if ( c->op == SLAP_CONFIG_EMIT ) { rc = 0; switch( c->type ) { case BDB_MODE: { char buf[64]; struct berval bv; bv.bv_len = snprintf( buf, sizeof(buf), "0%o", bdb->bi_dbenv_mode ); if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { bv.bv_val = buf; value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } } break; case BDB_CHKPT: if ( bdb->bi_txn_cp ) { char buf[64]; struct berval bv; bv.bv_len = snprintf( buf, sizeof(buf), "%ld %ld", (long) bdb->bi_txn_cp_kbyte, (long) bdb->bi_txn_cp_min ); if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { bv.bv_val = buf; value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } } else { rc = 1; } break; case BDB_CRYPTFILE: if ( bdb->bi_db_crypt_file ) { c->value_string = ch_strdup( bdb->bi_db_crypt_file ); } else { rc = 1; } break; /* If a crypt file has been set, its contents are copied here. * But we don't want the key to be incorporated here. */ case BDB_CRYPTKEY: if ( !bdb->bi_db_crypt_file && !BER_BVISNULL( &bdb->bi_db_crypt_key )) { value_add_one( &c->rvalue_vals, &bdb->bi_db_crypt_key ); } else { rc = 1; } break; case BDB_DIRECTORY: if ( bdb->bi_dbenv_home ) { c->value_string = ch_strdup( bdb->bi_dbenv_home ); } else { rc = 1; } break; case BDB_CONFIG: if ( !( bdb->bi_flags & BDB_IS_OPEN ) && !bdb->bi_db_config ) { char buf[SLAP_TEXT_BUFLEN]; FILE *f = fopen( bdb->bi_db_config_path, "r" ); struct berval bv; if ( f ) { bdb->bi_flags |= BDB_HAS_CONFIG; while ( fgets( buf, sizeof(buf), f )) { ber_str2bv( buf, 0, 1, &bv ); if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\n' ) { bv.bv_len--; bv.bv_val[bv.bv_len] = '\0'; } /* shouldn't need this, but ... */ if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\r' ) { bv.bv_len--; bv.bv_val[bv.bv_len] = '\0'; } ber_bvarray_add( &bdb->bi_db_config, &bv ); } fclose( f ); } } if ( bdb->bi_db_config ) { int i; struct berval bv; bv.bv_val = c->log; for (i=0; !BER_BVISNULL(&bdb->bi_db_config[i]); i++) { bv.bv_len = sprintf( bv.bv_val, "{%d}%s", i, bdb->bi_db_config[i].bv_val ); value_add_one( &c->rvalue_vals, &bv ); } } if ( !c->rvalue_vals ) rc = 1; break; case BDB_NOSYNC: if ( bdb->bi_dbenv_xflags & DB_TXN_NOSYNC ) c->value_int = 1; break; case BDB_CHECKSUM: if ( bdb->bi_flags & BDB_CHKSUM ) c->value_int = 1; break; case BDB_INDEX: bdb_attr_index_unparse( bdb, &c->rvalue_vals ); if ( !c->rvalue_vals ) rc = 1; break; case BDB_LOCKD: rc = 1; if ( bdb->bi_lock_detect != DB_LOCK_DEFAULT ) { int i; for (i=0; !BER_BVISNULL(&bdb_lockd[i].word); i++) { if ( bdb->bi_lock_detect == (u_int32_t)bdb_lockd[i].mask ) { value_add_one( &c->rvalue_vals, &bdb_lockd[i].word ); rc = 0; break; } } } break; case BDB_SSTACK: c->value_int = bdb->bi_search_stack_depth; break; case BDB_PGSIZE: { struct bdb_db_pgsize *ps; char buf[SLAP_TEXT_BUFLEN]; struct berval bv; int rc = 1; bv.bv_val = buf; for ( ps = bdb->bi_pagesizes; ps; ps = ps->bdp_next ) { bv.bv_len = sprintf( buf, "%s %d", ps->bdp_name.bv_val, ps->bdp_size / 1024 ); value_add_one( &c->rvalue_vals, &bv ); rc = 0; } break; } } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { rc = 0; switch( c->type ) { case BDB_MODE: #if 0 /* FIXME: does it make any sense to change the mode, * if we don't exec a chmod()? */ bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE; break; #endif /* single-valued no-ops */ case BDB_LOCKD: case BDB_SSTACK: break; case BDB_CHKPT: if ( bdb->bi_txn_cp_task ) { struct re_s *re = bdb->bi_txn_cp_task; bdb->bi_txn_cp_task = NULL; ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) ) ldap_pvt_runqueue_stoptask( &slapd_rq, re ); ldap_pvt_runqueue_remove( &slapd_rq, re ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } bdb->bi_txn_cp = 0; break; case BDB_CONFIG: if ( c->valx < 0 ) { ber_bvarray_free( bdb->bi_db_config ); bdb->bi_db_config = NULL; } else { int i = c->valx; ch_free( bdb->bi_db_config[i].bv_val ); for (; bdb->bi_db_config[i].bv_val; i++) bdb->bi_db_config[i] = bdb->bi_db_config[i+1]; } bdb->bi_flags |= BDB_UPD_CONFIG|BDB_RE_OPEN; c->cleanup = bdb_cf_cleanup; break; /* Doesn't really make sense to change these on the fly; * the entire DB must be dumped and reloaded */ case BDB_CRYPTFILE: if ( bdb->bi_db_crypt_file ) { ch_free( bdb->bi_db_crypt_file ); bdb->bi_db_crypt_file = NULL; } /* FALLTHRU */ case BDB_CRYPTKEY: if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) { ch_free( bdb->bi_db_crypt_key.bv_val ); BER_BVZERO( &bdb->bi_db_crypt_key ); } break; case BDB_DIRECTORY: bdb->bi_flags |= BDB_RE_OPEN; bdb->bi_flags ^= BDB_HAS_CONFIG; ch_free( bdb->bi_dbenv_home ); bdb->bi_dbenv_home = NULL; ch_free( bdb->bi_db_config_path ); bdb->bi_db_config_path = NULL; c->cleanup = bdb_cf_cleanup; ldap_pvt_thread_pool_purgekey( bdb->bi_dbenv ); break; case BDB_NOSYNC: bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, 0 ); break; case BDB_CHECKSUM: bdb->bi_flags &= ~BDB_CHKSUM; break; case BDB_INDEX: if ( c->valx == -1 ) { int i; /* delete all (FIXME) */ for ( i = 0; i < bdb->bi_nattrs; i++ ) { bdb->bi_attrs[i]->ai_indexmask |= BDB_INDEX_DELETING; } bdb->bi_flags |= BDB_DEL_INDEX; c->cleanup = bdb_cf_cleanup; } else { struct berval bv, def = BER_BVC("default"); char *ptr; for (ptr = c->line; !isspace( (unsigned char) *ptr ); ptr++); bv.bv_val = c->line; bv.bv_len = ptr - bv.bv_val; if ( bvmatch( &bv, &def )) { bdb->bi_defaultmask = 0; } else { int i; char **attrs; char sep; sep = bv.bv_val[ bv.bv_len ]; bv.bv_val[ bv.bv_len ] = '\0'; attrs = ldap_str2charray( bv.bv_val, "," ); for ( i = 0; attrs[ i ]; i++ ) { AttributeDescription *ad = NULL; const char *text; AttrInfo *ai; slap_str2ad( attrs[ i ], &ad, &text ); /* if we got here... */ assert( ad != NULL ); ai = bdb_attr_mask( bdb, ad ); /* if we got here... */ assert( ai != NULL ); ai->ai_indexmask |= BDB_INDEX_DELETING; bdb->bi_flags |= BDB_DEL_INDEX; c->cleanup = bdb_cf_cleanup; } bv.bv_val[ bv.bv_len ] = sep; ldap_charray_free( attrs ); } } break; /* doesn't make sense on the fly; the DB file must be * recreated */ case BDB_PGSIZE: { struct bdb_db_pgsize *ps, **prev; int i; for ( i = 0, prev = &bdb->bi_pagesizes, ps = *prev; ps; prev = &ps->bdp_next, ps = ps->bdp_next, i++ ) { if ( c->valx == -1 || i == c->valx ) { *prev = ps->bdp_next; ch_free( ps ); ps = *prev; if ( i == c->valx ) break; } } } break; } return rc; } switch( c->type ) { case BDB_MODE: if ( ASCII_DIGIT( c->argv[1][0] ) ) { long mode; char *next; errno = 0; mode = strtol( c->argv[1], &next, 0 ); if ( errno != 0 || next == c->argv[1] || next[0] != '\0' ) { fprintf( stderr, "%s: " "unable to parse mode=\"%s\".\n", c->log, c->argv[1] ); return 1; } bdb->bi_dbenv_mode = mode; } else { char *m = c->argv[1]; int who, what, mode = 0; if ( strlen( m ) != STRLENOF("-rwxrwxrwx") ) { return 1; } if ( m[0] != '-' ) { return 1; } m++; for ( who = 0; who < 3; who++ ) { for ( what = 0; what < 3; what++, m++ ) { if ( m[0] == '-' ) { continue; } else if ( m[0] != "rwx"[what] ) { return 1; } mode += ((1 << (2 - what)) << 3*(2 - who)); } } bdb->bi_dbenv_mode = mode; } break; case BDB_CHKPT: { long l; bdb->bi_txn_cp = 1; if ( lutil_atolx( &l, c->argv[1], 0 ) != 0 ) { fprintf( stderr, "%s: " "invalid kbyte \"%s\" in \"checkpoint\".\n", c->log, c->argv[1] ); return 1; } bdb->bi_txn_cp_kbyte = l; if ( lutil_atolx( &l, c->argv[2], 0 ) != 0 ) { fprintf( stderr, "%s: " "invalid minutes \"%s\" in \"checkpoint\".\n", c->log, c->argv[2] ); return 1; } bdb->bi_txn_cp_min = l; /* If we're in server mode and time-based checkpointing is enabled, * submit a task to perform periodic checkpoints. */ if ((slapMode & SLAP_SERVER_MODE) && bdb->bi_txn_cp_min ) { struct re_s *re = bdb->bi_txn_cp_task; if ( re ) { re->interval.tv_sec = bdb->bi_txn_cp_min * 60; } else { if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { fprintf( stderr, "%s: " "\"checkpoint\" must occur after \"suffix\".\n", c->log ); return 1; } ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); bdb->bi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq, bdb->bi_txn_cp_min * 60, bdb_checkpoint, bdb, LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } } } break; case BDB_CONFIG: { char *ptr = c->line; struct berval bv; if ( c->op == SLAP_CONFIG_ADD ) { ptr += STRLENOF("dbconfig"); while (!isspace((unsigned char)*ptr)) ptr++; while (isspace((unsigned char)*ptr)) ptr++; } if ( bdb->bi_flags & BDB_IS_OPEN ) { bdb->bi_flags |= BDB_UPD_CONFIG|BDB_RE_OPEN; c->cleanup = bdb_cf_cleanup; } else { /* If we're just starting up... */ FILE *f; /* If a DB_CONFIG file exists, or we don't know the path * to the DB_CONFIG file, ignore these directives */ if (( bdb->bi_flags & BDB_HAS_CONFIG ) || !bdb->bi_db_config_path ) break; f = fopen( bdb->bi_db_config_path, "a" ); if ( f ) { /* FIXME: EBCDIC probably needs special handling */ fprintf( f, "%s\n", ptr ); fclose( f ); } } ber_str2bv( ptr, 0, 1, &bv ); ber_bvarray_add( &bdb->bi_db_config, &bv ); } break; case BDB_CRYPTFILE: rc = lutil_get_filed_password( c->value_string, &bdb->bi_db_crypt_key ); if ( rc == 0 ) { bdb->bi_db_crypt_file = c->value_string; } break; /* Cannot set key if file was already set */ case BDB_CRYPTKEY: if ( bdb->bi_db_crypt_file ) { rc = 1; } else { bdb->bi_db_crypt_key = c->value_bv; } break; case BDB_DIRECTORY: { FILE *f; char *ptr, *testpath; int len; len = strlen( c->value_string ); testpath = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DUMMY") + 1 ); ptr = lutil_strcopy( testpath, c->value_string ); *ptr++ = LDAP_DIRSEP[0]; strcpy( ptr, "DUMMY" ); f = fopen( testpath, "w" ); if ( f ) { fclose( f ); unlink( testpath ); } ch_free( testpath ); if ( !f ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid path: %s", c->log, strerror( errno )); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } if ( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home ); bdb->bi_dbenv_home = c->value_string; /* See if a DB_CONFIG file already exists here */ if ( bdb->bi_db_config_path ) ch_free( bdb->bi_db_config_path ); bdb->bi_db_config_path = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DB_CONFIG") + 1 ); ptr = lutil_strcopy( bdb->bi_db_config_path, bdb->bi_dbenv_home ); *ptr++ = LDAP_DIRSEP[0]; strcpy( ptr, "DB_CONFIG" ); f = fopen( bdb->bi_db_config_path, "r" ); if ( f ) { bdb->bi_flags |= BDB_HAS_CONFIG; fclose(f); } } break; case BDB_NOSYNC: if ( c->value_int ) bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC; else bdb->bi_dbenv_xflags &= ~DB_TXN_NOSYNC; if ( bdb->bi_flags & BDB_IS_OPEN ) { bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, c->value_int ); } break; case BDB_CHECKSUM: if ( c->value_int ) bdb->bi_flags |= BDB_CHKSUM; else bdb->bi_flags &= ~BDB_CHKSUM; break; case BDB_INDEX: rc = bdb_attr_index_config( bdb, c->fname, c->lineno, c->argc - 1, &c->argv[1], &c->reply); if( rc != LDAP_SUCCESS ) return 1; if (( bdb->bi_flags & BDB_IS_OPEN ) && !bdb->bi_index_task ) { /* Start the task as soon as we finish here. Set a long * interval (10 hours) so that it only gets scheduled once. */ if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { fprintf( stderr, "%s: " "\"index\" must occur after \"suffix\".\n", c->log ); return 1; } ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); bdb->bi_index_task = ldap_pvt_runqueue_insert( &slapd_rq, 36000, bdb_online_index, c->be, LDAP_XSTRING(bdb_online_index), c->be->be_suffix[0].bv_val ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } break; case BDB_LOCKD: rc = verb_to_mask( c->argv[1], bdb_lockd ); if ( BER_BVISNULL(&bdb_lockd[rc].word) ) { fprintf( stderr, "%s: " "bad policy (%s) in \"lockDetect <policy>\" line\n", c->log, c->argv[1] ); return 1; } bdb->bi_lock_detect = (u_int32_t)rc; break; case BDB_SSTACK: if ( c->value_int < MINIMUM_SEARCH_STACK_DEPTH ) { fprintf( stderr, "%s: depth %d too small, using %d\n", c->log, c->value_int, MINIMUM_SEARCH_STACK_DEPTH ); c->value_int = MINIMUM_SEARCH_STACK_DEPTH; } bdb->bi_search_stack_depth = c->value_int; break; case BDB_PGSIZE: { struct bdb_db_pgsize *ps, **prev; int i, s; s = atoi(c->argv[2]); if ( s < 1 || s > 64 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: size must be > 0 and <= 64: %d", c->log, s ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } i = strlen(c->argv[1]); ps = ch_malloc( sizeof(struct bdb_db_pgsize) + i + 1 ); ps->bdp_next = NULL; ps->bdp_name.bv_len = i; ps->bdp_name.bv_val = (char *)(ps+1); strcpy( ps->bdp_name.bv_val, c->argv[1] ); ps->bdp_size = s * 1024; for ( prev = &bdb->bi_pagesizes; *prev; prev = &(*prev)->bdp_next ) ; *prev = ps; } break; } return 0; }
static krb5_error_code LDAP__lookup_princ(krb5_context context, HDB *db, const char *princname, const char *userid, LDAPMessage **msg) { struct berval namebv, quotedp; krb5_error_code ret; int rc; char *filter = NULL; ret = LDAP__connect(context, db); if (ret) return ret; /* * Quote searches that contain filter language, this quote * searches for *@REALM, which takes very long time. */ ber_str2bv(princname, 0, 0, &namebv); if (ldap_bv2escaped_filter_value(&namebv, "edp) != 0) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } rc = asprintf(&filter, "(&(objectClass=krb5Principal)(krb5PrincipalName=%s))", quotedp.bv_val); ber_memfree(quotedp.bv_val); if (rc < 0) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_no_size_limit(context, HDB2LDAP(db)); if (ret) goto out; rc = ldap_search_ext_s(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE, filter, krb5kdcentry_attrs, 0, NULL, NULL, NULL, 0, msg); if (check_ldap(context, db, rc)) { ret = HDB_ERR_NOENTRY; krb5_set_error_message(context, ret, "ldap_search_ext_s: " "filter: %s - error: %s", filter, ldap_err2string(rc)); goto out; } if (userid && ldap_count_entries(HDB2LDAP(db), *msg) == 0) { free(filter); filter = NULL; ldap_msgfree(*msg); *msg = NULL; ber_str2bv(userid, 0, 0, &namebv); if (ldap_bv2escaped_filter_value(&namebv, "edp) != 0) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } rc = asprintf(&filter, "(&(|(objectClass=sambaSamAccount)(objectClass=%s))(uid=%s))", structural_object, quotedp.bv_val); ber_memfree(quotedp.bv_val); if (rc < 0) { ret = ENOMEM; krb5_set_error_message(context, ret, "asprintf: out of memory"); goto out; } ret = LDAP_no_size_limit(context, HDB2LDAP(db)); if (ret) goto out; rc = ldap_search_ext_s(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE, filter, krb5kdcentry_attrs, 0, NULL, NULL, NULL, 0, msg); if (check_ldap(context, db, rc)) { ret = HDB_ERR_NOENTRY; krb5_set_error_message(context, ret, "ldap_search_ext_s: filter: %s error: %s", filter, ldap_err2string(rc)); goto out; } } ret = 0; out: if (filter) free(filter); return ret; }