Commit 6a9bf976 authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

add URI search to sets; documentation to come...

parent 1df6d762
......@@ -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;
AciSetCookie *cp = (AciSetCookie *)cookie;
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 );
}
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;
}
if (dnNormalize(0, NULL, NULL, name, &ndn, cp->op->o_tmpmemctx) == LDAP_SUCCESS) {
/* 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,10 +1201,25 @@ 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 );
fname, lineno, style );
acl_usage();
}
......
......@@ -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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment