mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
add URI search to sets; documentation to come...
This commit is contained in:
parent
1df6d76269
commit
6a9bf9765e
@ -120,6 +120,7 @@ typedef struct AciSetCookie {
|
||||
} AciSetCookie;
|
||||
|
||||
SLAP_SET_GATHER aci_set_gather;
|
||||
SLAP_SET_GATHER aci_set_gather2;
|
||||
static int aci_match_set ( struct berval *subj, Operation *op,
|
||||
Entry *e, int setref );
|
||||
|
||||
@ -1311,14 +1312,60 @@ dn_match_cleanup:;
|
||||
if ( b->a_set_pat.bv_len != 0 ) {
|
||||
struct berval bv;
|
||||
char buf[ACL_BUF_SIZE];
|
||||
if( b->a_set_style == ACL_STYLE_REGEX ){
|
||||
|
||||
if ( b->a_set_style == ACL_STYLE_EXPAND ) {
|
||||
int tmp_nmatch;
|
||||
regmatch_t tmp_matches[2],
|
||||
*tmp_matchesp = tmp_matches;
|
||||
int rc = 0;
|
||||
|
||||
bv.bv_len = sizeof(buf) - 1;
|
||||
bv.bv_val = buf;
|
||||
|
||||
rc = 0;
|
||||
|
||||
switch ( a->acl_dn_style ) {
|
||||
case ACL_STYLE_REGEX:
|
||||
if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
|
||||
tmp_matchesp = matches;
|
||||
tmp_nmatch = nmatch;
|
||||
break;
|
||||
}
|
||||
|
||||
/* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
|
||||
case ACL_STYLE_BASE:
|
||||
tmp_matches[0].rm_so = 0;
|
||||
tmp_matches[0].rm_eo = e->e_nname.bv_len;
|
||||
tmp_nmatch = 1;
|
||||
break;
|
||||
|
||||
case ACL_STYLE_ONE:
|
||||
case ACL_STYLE_SUBTREE:
|
||||
case ACL_STYLE_CHILDREN:
|
||||
tmp_matches[0].rm_so = 0;
|
||||
tmp_matches[0].rm_eo = e->e_nname.bv_len;
|
||||
tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
|
||||
tmp_matches[1].rm_eo = e->e_nname.bv_len;
|
||||
tmp_nmatch = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* error */
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( rc ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( string_expand( &bv, &b->a_set_pat,
|
||||
e->e_ndn, nmatch, matches ) )
|
||||
e->e_nname.bv_val,
|
||||
tmp_nmatch, tmp_matchesp ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
}else{
|
||||
bv = b->a_set_pat;
|
||||
}
|
||||
@ -1744,28 +1791,198 @@ aci_get_part(
|
||||
return(bv->bv_len);
|
||||
}
|
||||
|
||||
typedef struct aci_set_gather_t {
|
||||
SetCookie *cookie;
|
||||
AttributeDescription *desc;
|
||||
BerVarray bvals;
|
||||
} aci_set_gather_t;
|
||||
|
||||
static int
|
||||
aci_set_cb_gather( Operation *op, SlapReply *rs )
|
||||
{
|
||||
aci_set_gather_t *p = (aci_set_gather_t *)op->o_callback->sc_private;
|
||||
|
||||
if ( rs->sr_type == REP_SEARCH ) {
|
||||
BerVarray bvals = NULL;
|
||||
|
||||
if ( p->desc == slap_schema.si_ad_entryDN ) {
|
||||
bvals = slap_sl_malloc( sizeof( BerValue ) * 2, op->o_tmpmemctx );
|
||||
ber_dupbv_x( &bvals[ 0 ], &rs->sr_entry->e_nname, op->o_tmpmemctx );
|
||||
BER_BVZERO( &bvals[ 1 ] );
|
||||
|
||||
} else {
|
||||
Attribute *a;
|
||||
|
||||
a = attr_find( rs->sr_entry->e_attrs, p->desc );
|
||||
if ( a != NULL ) {
|
||||
int i;
|
||||
|
||||
for ( i = 0; !BER_BVISNULL( &a->a_nvals[ i ] ); i++ )
|
||||
;
|
||||
|
||||
bvals = slap_sl_malloc( sizeof( BerValue ) * ( i + 1 ), op->o_tmpmemctx );
|
||||
for ( i = 0; !BER_BVISNULL( &a->a_nvals[ i ] ); i++ ) {
|
||||
ber_dupbv_x( &bvals[ i ], &a->a_nvals[ i ], op->o_tmpmemctx );
|
||||
}
|
||||
BER_BVZERO( &bvals[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( bvals ) {
|
||||
p->bvals = slap_set_join( p->cookie, p->bvals, '|', bvals );
|
||||
}
|
||||
|
||||
} else {
|
||||
assert( rs->sr_type == REP_RESULT );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BerVarray
|
||||
aci_set_gather (SetCookie *cookie, struct berval *name, struct berval *attr)
|
||||
aci_set_gather( SetCookie *cookie, struct berval *name, struct berval *attr )
|
||||
{
|
||||
AciSetCookie *cp = (AciSetCookie *)cookie;
|
||||
BerVarray bvals = NULL;
|
||||
struct berval ndn;
|
||||
int rc = 0;
|
||||
LDAPURLDesc *ludp = NULL;
|
||||
Operation op2 = { 0 };
|
||||
SlapReply rs = {REP_RESULT};
|
||||
AttributeName anlist[2];
|
||||
slap_callback cb = { NULL, aci_set_cb_gather, NULL, NULL };
|
||||
aci_set_gather_t p = { 0 };
|
||||
struct berval aname;
|
||||
const char *text = NULL;
|
||||
|
||||
/* this routine needs to return the bervals instead of
|
||||
* plain strings, since syntax is not known. It should
|
||||
* also return the syntax or some "comparison cookie".
|
||||
*/
|
||||
if ( strncasecmp( name->bv_val, "ldap:///", STRLENOF( "ldap:///" ) ) != 0 ) {
|
||||
return aci_set_gather2( cookie, name, attr );
|
||||
}
|
||||
|
||||
if (dnNormalize(0, NULL, NULL, name, &ndn, cp->op->o_tmpmemctx) == LDAP_SUCCESS) {
|
||||
rc = ldap_url_parse( name->bv_val, &ludp );
|
||||
if ( rc != LDAP_URL_SUCCESS ) {
|
||||
rc = LDAP_PROTOCOL_ERROR;
|
||||
goto url_done;
|
||||
}
|
||||
|
||||
if ( ( ludp->lud_host && ludp->lud_host[0] ) || ludp->lud_exts )
|
||||
{
|
||||
/* host part must be empty */
|
||||
/* extensions parts must be empty */
|
||||
rc = LDAP_PROTOCOL_ERROR;
|
||||
goto url_done;
|
||||
}
|
||||
|
||||
/* Grab the filter */
|
||||
if ( ludp->lud_filter ) {
|
||||
op2.ors_filter = str2filter_x( cp->op, ludp->lud_filter );
|
||||
if ( op2.ors_filter == NULL ) {
|
||||
rc = LDAP_PROTOCOL_ERROR;
|
||||
goto url_done;
|
||||
}
|
||||
ber_str2bv( ludp->lud_filter, 0, 0, &op2.ors_filterstr );
|
||||
}
|
||||
|
||||
/* Grab the searchbase */
|
||||
ber_str2bv( ludp->lud_dn, 0, 0, &op2.o_req_dn );
|
||||
|
||||
/* Grab the scope */
|
||||
op2.ors_scope = ludp->lud_scope;
|
||||
|
||||
if ( ludp->lud_attrs && ludp->lud_attrs[0] ) {
|
||||
if ( ludp->lud_attrs[1] ) {
|
||||
rc = LDAP_PROTOCOL_ERROR;
|
||||
goto url_done;
|
||||
}
|
||||
ber_str2bv( ludp->lud_attrs[0], 0, 0, &aname );
|
||||
|
||||
} else {
|
||||
aname = *attr;
|
||||
}
|
||||
|
||||
rc = slap_bv2ad( &aname, &p.desc, &text );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
goto url_done;
|
||||
}
|
||||
p.cookie = cookie;
|
||||
|
||||
rc = dnNormalize( 0, NULL, NULL, &op2.o_req_dn,
|
||||
&op2.o_req_ndn, cp->op->o_tmpmemctx );
|
||||
|
||||
op2.o_bd = select_backend( &op2.o_req_ndn, 0, 1 );
|
||||
if ( ( op2.o_bd == NULL ) || ( op2.o_bd->be_search == NULL ) ) {
|
||||
rc = LDAP_NO_SUCH_OBJECT;
|
||||
goto url_done;
|
||||
}
|
||||
|
||||
op2.o_tag = LDAP_REQ_SEARCH;
|
||||
op2.o_protocol = LDAP_VERSION3;
|
||||
op2.o_ndn = op2.o_bd->be_rootndn;
|
||||
op2.o_callback = &cb;
|
||||
op2.o_time = slap_get_time();
|
||||
op2.o_do_not_cache = 1;
|
||||
op2.o_is_auth_check = 0;
|
||||
op2.o_threadctx = cp->op->o_threadctx;
|
||||
op2.o_tmpmemctx = cp->op->o_tmpmemctx;
|
||||
op2.o_tmpmfuncs = cp->op->o_tmpmfuncs;
|
||||
#ifdef LDAP_SLAPI
|
||||
op2.o_pb = cp->op->o_pb;
|
||||
#endif
|
||||
op2.o_conn = cp->op->o_conn;
|
||||
op2.o_connid = cp->op->o_connid;
|
||||
ber_dupbv_x( &op2.o_req_dn, &op2.o_req_ndn, cp->op->o_tmpmemctx );
|
||||
op2.ors_slimit = SLAP_NO_LIMIT;
|
||||
op2.ors_tlimit = SLAP_NO_LIMIT;
|
||||
anlist[0].an_name = p.desc->ad_cname;
|
||||
anlist[0].an_desc = p.desc;
|
||||
BER_BVZERO( &anlist[1].an_name );
|
||||
op2.ors_attrs = anlist;
|
||||
op2.ors_attrsonly = 0;
|
||||
op2.o_sync_slog_size = -1;
|
||||
|
||||
cb.sc_private = &p;
|
||||
|
||||
rc = op2.o_bd->be_search( &op2, &rs );
|
||||
if ( rc != 0 ) {
|
||||
goto url_done;
|
||||
}
|
||||
|
||||
url_done:;
|
||||
if ( op2.ors_filter ) {
|
||||
filter_free_x( cp->op, op2.ors_filter );
|
||||
}
|
||||
slap_sl_free( op2.o_req_ndn.bv_val, cp->op->o_tmpmemctx );
|
||||
ldap_free_urldesc( ludp );
|
||||
|
||||
return p.bvals;
|
||||
}
|
||||
|
||||
BerVarray
|
||||
aci_set_gather2( SetCookie *cookie, struct berval *name, struct berval *attr )
|
||||
{
|
||||
AciSetCookie *cp = (AciSetCookie *)cookie;
|
||||
BerVarray bvals = NULL;
|
||||
struct berval ndn;
|
||||
int rc = 0;
|
||||
|
||||
/* this routine needs to return the bervals instead of
|
||||
* plain strings, since syntax is not known. It should
|
||||
* also return the syntax or some "comparison cookie".
|
||||
*/
|
||||
rc = dnNormalize( 0, NULL, NULL, name, &ndn, cp->op->o_tmpmemctx );
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
const char *text;
|
||||
AttributeDescription *desc = NULL;
|
||||
if (slap_bv2ad(attr, &desc, &text) == LDAP_SUCCESS) {
|
||||
backend_attribute(cp->op,
|
||||
cp->e, &ndn, desc, &bvals, ACL_NONE);
|
||||
if ( slap_bv2ad( attr, &desc, &text ) == LDAP_SUCCESS ) {
|
||||
backend_attribute( cp->op,
|
||||
cp->e, &ndn, desc, &bvals, ACL_NONE );
|
||||
}
|
||||
slap_sl_free(ndn.bv_val, cp->op->o_tmpmemctx);
|
||||
slap_sl_free( ndn.bv_val, cp->op->o_tmpmemctx );
|
||||
}
|
||||
return(bvals);
|
||||
|
||||
return( bvals );
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -601,11 +601,14 @@ parse_acl(
|
||||
break;
|
||||
|
||||
case ACL_STYLE_EXPAND:
|
||||
#if 0
|
||||
/* FIXME: now it's legal... */
|
||||
fprintf( stderr, "%s: line %d: "
|
||||
"\"expand\" style used "
|
||||
"in conjunction with "
|
||||
"\"expand\" modifier (ignored)\n",
|
||||
fname, lineno );
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1198,7 +1201,22 @@ parse_acl(
|
||||
}
|
||||
|
||||
if ( strcasecmp( left, "set" ) == 0 ) {
|
||||
if (sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE) {
|
||||
switch ( sty ) {
|
||||
/* deprecated */
|
||||
case ACL_STYLE_REGEX:
|
||||
fprintf( stderr, "%s: line %d: "
|
||||
"deprecated set style "
|
||||
"\"regex\" in <by> clause; "
|
||||
"use \"expand\" instead\n",
|
||||
fname, lineno );
|
||||
sty = ACL_STYLE_EXPAND;
|
||||
/* FALLTHRU */
|
||||
|
||||
case ACL_STYLE_BASE:
|
||||
case ACL_STYLE_EXPAND:
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf( stderr, "%s: line %d: "
|
||||
"inappropriate style \"%s\" in by clause\n",
|
||||
fname, lineno, style );
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "slap.h"
|
||||
#include "sets.h"
|
||||
|
||||
static BerVarray set_join (SetCookie *cp, BerVarray lset, int op, BerVarray rset);
|
||||
static BerVarray set_chase (SLAP_SET_GATHER gatherer,
|
||||
SetCookie *cookie, BerVarray set, struct berval *attr, int closure);
|
||||
static int set_samedn (char *dn1, char *dn2);
|
||||
@ -45,8 +44,8 @@ slap_set_dispose (SetCookie *cp, BerVarray set)
|
||||
ber_bvarray_free_x(set, cp->op->o_tmpmemctx);
|
||||
}
|
||||
|
||||
static BerVarray
|
||||
set_join (SetCookie *cp, BerVarray lset, int op, BerVarray rset)
|
||||
BerVarray
|
||||
slap_set_join (SetCookie *cp, BerVarray lset, int op, BerVarray rset)
|
||||
{
|
||||
BerVarray set;
|
||||
long i, j, last;
|
||||
@ -156,7 +155,7 @@ set_chase (SLAP_SET_GATHER gatherer,
|
||||
for (i = 0; set[i].bv_val; i++) {
|
||||
vals = (gatherer)(cp, &set[i], &bv);
|
||||
if (vals != NULL)
|
||||
nset = set_join(cp, nset, '|', vals);
|
||||
nset = slap_set_join(cp, nset, '|', vals);
|
||||
}
|
||||
slap_set_dispose(cp, set);
|
||||
|
||||
@ -164,7 +163,7 @@ set_chase (SLAP_SET_GATHER gatherer,
|
||||
for (i = 0; nset[i].bv_val; i++) {
|
||||
vals = (gatherer)(cp, &nset[i], &bv);
|
||||
if (vals != NULL) {
|
||||
nset = set_join(cp, nset, '|', vals);
|
||||
nset = slap_set_join(cp, nset, '|', vals);
|
||||
if (nset == NULL)
|
||||
break;
|
||||
}
|
||||
@ -255,7 +254,7 @@ slap_set_filter (SLAP_SET_GATHER gatherer,
|
||||
op = (long)SF_POP();
|
||||
lset = SF_POP();
|
||||
SF_POP();
|
||||
set = set_join(cp, lset, op, set);
|
||||
set = slap_set_join(cp, lset, op, set);
|
||||
if (set == NULL)
|
||||
SF_ERROR(memory);
|
||||
SF_PUSH(set);
|
||||
@ -276,7 +275,7 @@ slap_set_filter (SLAP_SET_GATHER gatherer,
|
||||
} else if (IS_OP(SF_TOP())) {
|
||||
op = (long)SF_POP();
|
||||
lset = SF_POP();
|
||||
set = set_join(cp, lset, op, set);
|
||||
set = slap_set_join(cp, lset, op, set);
|
||||
if (set == NULL)
|
||||
SF_ERROR(memory);
|
||||
SF_PUSH(set);
|
||||
@ -290,10 +289,8 @@ slap_set_filter (SLAP_SET_GATHER gatherer,
|
||||
case '[':
|
||||
if ((SF_TOP() == (void *)'/') || IS_SET(SF_TOP()))
|
||||
SF_ERROR(syntax);
|
||||
for ( len = 0;
|
||||
(c = *filter++) && (c != ']');
|
||||
len++)
|
||||
{ }
|
||||
for ( len = 0; (c = *filter++) && (c != ']'); len++ )
|
||||
;
|
||||
if (c == 0)
|
||||
SF_ERROR(syntax);
|
||||
|
||||
@ -365,8 +362,8 @@ slap_set_filter (SLAP_SET_GATHER gatherer,
|
||||
SF_POP();
|
||||
fb2.bv_val = filter;
|
||||
fb2.bv_len = len;
|
||||
set = set_chase(gatherer,
|
||||
cp, SF_POP(), &fb2, c == '*');
|
||||
set = set_chase( gatherer,
|
||||
cp, SF_POP(), &fb2, c == '*' );
|
||||
if (set == NULL)
|
||||
SF_ERROR(memory);
|
||||
if (c == '*')
|
||||
@ -387,7 +384,7 @@ slap_set_filter (SLAP_SET_GATHER gatherer,
|
||||
} else if (IS_OP(SF_TOP())) {
|
||||
op = (long)SF_POP();
|
||||
lset = SF_POP();
|
||||
set = set_join(cp, lset, op, set);
|
||||
set = slap_set_join(cp, lset, op, set);
|
||||
if (set == NULL)
|
||||
SF_ERROR(memory);
|
||||
} else {
|
||||
|
@ -40,6 +40,9 @@ LDAP_SLAPD_F (int) slap_set_filter(
|
||||
SetCookie *cookie, struct berval *filter,
|
||||
struct berval *user, struct berval *this, BerVarray *results);
|
||||
|
||||
LDAP_SLAPD_F (BerVarray) slap_set_join(SetCookie *cp, BerVarray lset,
|
||||
int op, BerVarray rset);
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user