add group authz

This commit is contained in:
Pierangelo Masarati 2004-04-25 23:59:06 +00:00
parent 63b1e663e2
commit ff0df4b6aa
2 changed files with 116 additions and 11 deletions

View File

@ -214,6 +214,9 @@ or a set of identities; it can take three forms:
.B u[<mech>[<realm>]]:<pattern>
.RE
.RS
.B group[/objectClass[/attributeType]]:<pattern>
.RE
.RS
.B <pattern>
.RE
.RS
@ -262,6 +265,18 @@ and eventually a SASL
for those mechanisms that support one.
The need to allow the specification of a mechanism is still debated,
and users are strongly discouraged to rely on this possibility.
The fourth form is a group specification, consisting of the keyword
.BR group ,
optionally followed by the specification of the group
.B objectClass
and member
.BR attributeType .
The group with DN
.B <pattern>
is searched with base scope, and in case of match, the values of the
member
.B attributeType
are searched for the asserted DN.
For backwards compatibility, if no identity type is provided, i.e. only
.B <pattern>
is present, an

View File

@ -27,6 +27,7 @@
#include <limits.h>
#include <ldap_pvt.h>
#include "lutil.h"
#define SASLREGEX_REPLACE 10
@ -35,6 +36,7 @@
#define LDAP_X_SCOPE_CHILDREN ((ber_int_t) 0x0030)
#define LDAP_X_SCOPE_SUBTREE ((ber_int_t) 0x0040)
#define LDAP_X_SCOPE_ONELEVEL ((ber_int_t) 0x0050)
#define LDAP_X_SCOPE_GROUP ((ber_int_t) 0x0060)
/*
* IDs in DNauthzid form can now have a type specifier, that
@ -311,6 +313,59 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);
}
return rc;
} else if ( strncasecmp( uri->bv_val, "group", STRLENOF( "group" ) ) == 0 )
{
struct berval group_dn = BER_BVNULL,
group_oc = BER_BVNULL,
member_at = BER_BVNULL;
char *tmp;
bv.bv_val = uri->bv_val + STRLENOF( "group" );
group_dn.bv_val = strchr( bv.bv_val, ':' );
if ( group_dn.bv_val == NULL ) {
/* last chance: assume it's a(n exact) DN ... */
bv.bv_val = uri->bv_val;
*scope = LDAP_X_SCOPE_EXACT;
goto is_dn;
}
if ( bv.bv_val[ 0 ] == '/' ) {
group_oc.bv_val = &bv.bv_val[ 1 ];
member_at.bv_val = strchr( group_oc.bv_val, '/' );
if ( member_at.bv_val ) {
group_oc.bv_len = member_at.bv_val - group_oc.bv_val;
member_at.bv_val++;
member_at.bv_len = group_dn.bv_val - member_at.bv_val;
} else {
group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
BER_BVSTR( &member_at, "member" );
}
} else {
BER_BVSTR( &group_oc, "groupOfNames" );
}
group_dn.bv_val++;
group_dn.bv_len = uri->bv_len - ( group_dn.bv_val - uri->bv_val );
fstr->bv_len = STRLENOF( "(&(objectClass=)(=" ) + group_oc.bv_len + member_at.bv_len;
fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
tmp = lutil_strncopy( fstr->bv_val, "(&(objectClass=", STRLENOF( "(&(objectClass=" ) );
tmp = lutil_strncopy( tmp, group_oc.bv_val, group_oc.bv_len );
tmp = lutil_strncopy( tmp, ")(", STRLENOF( ")(" ) );
tmp = lutil_strncopy( tmp, member_at.bv_val, member_at.bv_len );
tmp = lutil_strncopy( tmp, "=", STRLENOF( "=" ) );
rc = dnNormalize( 0, NULL, NULL, &group_dn, nbase, op->o_tmpmemctx );
if ( rc != LDAP_SUCCESS ) {
*scope = -1;
} else {
*scope = LDAP_X_SCOPE_GROUP;
}
return rc;
}
rc = ldap_url_parse( uri->bv_val, &ludp );
@ -434,7 +489,7 @@ int slap_sasl_rewrite_config(
int slap_sasl_rewrite_destroy( void )
{
if ( sasl_rwinfo ) {
rewrite_info_delete( sasl_rwinfo );
rewrite_info_delete( &sasl_rwinfo );
sasl_rwinfo = NULL;
}
@ -456,8 +511,6 @@ int slap_sasl_regexp_rewrite_config(
if ( sasl_rwinfo == NULL ) {
char *argvEngine[] = { "rewriteEngine", "on", NULL };
char *argvContext[] = { "rewriteContext", NULL, NULL };
char *argvFirstRule[] = { "rewriteRule", ".*",
"%{>" AUTHID_CONTEXT "(%0)}", ":", NULL };
/* initialize rewrite engine */
sasl_rwinfo = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
@ -749,6 +802,10 @@ int slap_sasl_match( Operation *opx, struct berval *rule,
Operation op = {0};
SlapReply rs = {REP_RESULT};
sm.dn = assertDN;
sm.match = 0;
cb.sc_private = &sm;
#ifdef NEW_LOGGING
LDAP_LOG( TRANSPORT, ENTRY,
"slap_sasl_match: comparing DN %s to rule %s\n",
@ -843,6 +900,40 @@ exact_match:
}
goto CONCLUDED;
case LDAP_X_SCOPE_GROUP: {
char *tmp;
/* Now filterstr looks like "(&(objectClass=<group_oc>)(<member_at>="
* we need to append the <assertDN> so that the <group_dn> is searched
* with scope "base", and the filter ensures that <assertDN> is
* member of the group */
tmp = ch_realloc( op.ors_filterstr.bv_val,
op.ors_filterstr.bv_len + assertDN->bv_len + STRLENOF( "))" ) + 1 );
if ( tmp == NULL ) {
rc = LDAP_NO_MEMORY;
goto CONCLUDED;
}
op.ors_filterstr.bv_val = tmp;
tmp = lutil_strcopy( &tmp[ op.ors_filterstr.bv_len ], assertDN->bv_val );
tmp = lutil_strcopy( tmp, "))" );
/* pass opx because str2filter_x may (and does) use o_tmpmfuncs */
op.ors_filter = str2filter_x( opx, op.ors_filterstr.bv_val );
if ( op.ors_filter == NULL ) {
rc = LDAP_PROTOCOL_ERROR;
goto CONCLUDED;
}
op.ors_scope = LDAP_SCOPE_BASE;
/* hijack match DN: use that of the group instead of the assertDN;
* assertDN is now in the filter */
sm.dn = &op.o_req_ndn;
/* do the search */
break;
}
default:
break;
}
@ -869,10 +960,6 @@ exact_match:
goto CONCLUDED;
}
sm.dn = assertDN;
sm.match = 0;
cb.sc_private = &sm;
op.o_tag = LDAP_REQ_SEARCH;
op.o_protocol = LDAP_VERSION3;
op.o_ndn = *authc;
@ -888,7 +975,9 @@ exact_match:
#endif
op.o_conn = opx->o_conn;
op.o_connid = opx->o_connid;
op.o_req_dn = op.o_req_ndn;
/* use req_ndn as req_dn instead of non-pretty base of uri */
if( !BER_BVISNULL( &op.o_req_dn ) ) ch_free( op.o_req_dn.bv_val );
ber_dupbv_x( &op.o_req_dn, &op.o_req_ndn, op.o_tmpmemctx );
op.oq_search.rs_slimit = 1;
op.oq_search.rs_tlimit = -1;
@ -901,10 +990,10 @@ exact_match:
}
CONCLUDED:
if( op.o_req_dn.bv_len ) ch_free( op.o_req_dn.bv_val );
if( op.o_req_ndn.bv_len ) slap_sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx );
if( !BER_BVISNULL( &op.o_req_dn ) ) slap_sl_free( op.o_req_dn.bv_val, opx->o_tmpmemctx );
if( !BER_BVISNULL( &op.o_req_ndn ) ) slap_sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx );
if( op.oq_search.rs_filter ) filter_free_x( opx, op.oq_search.rs_filter );
if( op.ors_filterstr.bv_len ) ch_free( op.ors_filterstr.bv_val );
if( !BER_BVISNULL( &op.ors_filterstr ) ) ch_free( op.ors_filterstr.bv_val );
#ifdef NEW_LOGGING
LDAP_LOG( TRANSPORT, ENTRY,
@ -1034,6 +1123,7 @@ void slap_sasl2dn( Operation *opx,
case LDAP_X_SCOPE_SUBTREE:
case LDAP_X_SCOPE_CHILDREN:
case LDAP_X_SCOPE_ONELEVEL:
case LDAP_X_SCOPE_GROUP:
/* correctly parsed, but illegal */
goto FINISHED;