saslAuthzTo/From stuff

when comparing IDs to saslAuthzTo/From values, the saslAuthzTo
saslAuthzFrom values can take different forms:

dn[.<style>]:<pattern>

<style> ::= 	exact		; exact match
		children	; children of <pattern> match
		subtree		; <pattern> or children of <pattern> match
		regex		; <pattern> is regcomp() & regexec()
if no <style>, then exact is assumed

u[.<mech>][/<realm>]:<user>

when parsing a proxyAuthz value, only exact DN is allowed,
and no <mech> can be specified.  <user> cannot contain ':'
and <mech> cannot contain '/'.
This commit is contained in:
Pierangelo Masarati 2003-12-13 23:02:59 +00:00
parent 0d8613c274
commit 4602c935f7
5 changed files with 185 additions and 42 deletions

View File

@ -699,8 +699,8 @@ static int parseProxyAuthz (
SlapReply *rs,
LDAPControl *ctrl )
{
int rc;
struct berval dn = { 0, NULL };
int rc;
struct berval dn = { 0, NULL };
if ( op->o_proxy_authz != SLAP_NO_CONTROL ) {
rs->sr_text = "proxy authorization control specified multiple times";
@ -748,16 +748,38 @@ static int parseProxyAuthz (
return LDAP_SUCCESS;
}
rc = slap_sasl_getdn( op->o_conn, op,
ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len,
NULL, &dn, SLAP_GETDN_AUTHZID );
/* FIXME: how can we get the realm? */
{
int rc;
char buf[ SLAP_LDAPDN_MAXLEN ];
struct berval id = { ctrl->ldctl_value.bv_len, (char *)buf },
user = { 0, NULL },
realm = { 0, NULL },
mech = { 0, NULL };
if( rc != LDAP_SUCCESS || !dn.bv_len ) {
if ( dn.bv_val ) {
ch_free( dn.bv_val );
strncpy( buf, ctrl->ldctl_value.bv_val, sizeof( buf ) );
rc = slap_parse_user( &id, &user, &realm, &mech );
if ( rc == LDAP_SUCCESS ) {
if ( mech.bv_len ) {
rs->sr_text = "mech not allowed in authzId";
return LDAP_PROXY_AUTHZ_FAILURE;
}
} else {
user = ctrl->ldctl_value;
}
rc = slap_sasl_getdn( op->o_conn, op,
user.bv_val, user.bv_len,
realm.bv_val, &dn, SLAP_GETDN_AUTHZID );
if( rc != LDAP_SUCCESS || !dn.bv_len ) {
if ( dn.bv_val ) {
ch_free( dn.bv_val );
}
rs->sr_text = "authzId mapping failed";
return LDAP_PROXY_AUTHZ_FAILURE;
}
rs->sr_text = "authzId mapping failed";
return LDAP_PROXY_AUTHZ_FAILURE;
}
#ifdef NEW_LOGGING

View File

@ -983,6 +983,9 @@ LDAP_SLAPD_F (int) slap_sasl_getdn( Connection *conn, Operation *op,
/*
* saslauthz.c
*/
LDAP_SLAPD_F (int) slap_parse_user LDAP_P((
struct berval *id, struct berval *user,
struct berval *realm, struct berval *mech ));
LDAP_SLAPD_F (void) slap_sasl2dn LDAP_P((
Operation *op,
struct berval *saslname,

View File

@ -1714,7 +1714,6 @@ static struct berval ext_bv = BER_BVC( "EXTERNAL" );
int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len,
char *user_realm, struct berval *dn, int flags )
{
char *c1;
int rc, is_dn = SET_NONE, do_norm = 1;
struct berval dn2, *mech;
@ -1796,22 +1795,38 @@ int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len,
/* Username strings */
if( is_dn == SET_U ) {
char *p, *realm;
char *p;
struct berval realm = { 0, NULL }, c1 = *dn;
len = dn->bv_len + sizeof("uid=")-1 + sizeof(",cn=auth")-1;
#if 0
/* username may have embedded realm name */
/* FIXME:
* 1) userids can legally have embedded '@' chars
* 2) we're mucking with memory we do not possess
* 3) this should not be required, since we're
* mostly doing strncpy's so we know how much
* memory to copy ...
* userids can legally have embedded '@' chars;
* the relm should be set by those mechanisms
* that support it by means of the user_realm
* variable
*/
if( ( realm = strrchr( dn->bv_val, '@') ) ) {
*realm++ = '\0';
len += sizeof(",cn=")-2;
} else if( user_realm && *user_realm ) {
len += strlen( user_realm ) + sizeof(",cn=")-1;
if( ( realm.bv_val = strrchr( dn->bv_val, '@') ) ) {
char *r = realm.bv_val;
realm.bv_val++;
realm.bv_len = dn->bv_len - ( realm.bv_val - dn->bv_val );
len += sizeof( ",cn=" ) - 2;
c1.bv_len -= realm.bv_len + 1;
if ( strchr( dn->bv_val, '@') == r ) {
/* FIXME: ambiguity, is it the realm
* or something else? */
}
} else
#endif
if( user_realm && *user_realm ) {
realm.bv_val = user_realm;
realm.bv_len = strlen( user_realm );
len += realm.bv_len + sizeof(",cn=") - 1;
}
if( mech->bv_len ) {
@ -1819,7 +1834,6 @@ int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len,
}
/* Build the new dn */
c1 = dn->bv_val;
dn->bv_val = sl_malloc( len+1, op->o_tmpmemctx );
if( dn->bv_val == NULL ) {
#ifdef NEW_LOGGING
@ -1832,16 +1846,11 @@ int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len,
return LDAP_OTHER;
}
p = lutil_strcopy( dn->bv_val, "uid=" );
p = lutil_strncopy( p, c1, dn->bv_len );
p = lutil_strncopy( p, c1.bv_val, c1.bv_len );
if( realm ) {
int rlen = dn->bv_len - ( realm - c1 );
if( realm.bv_len ) {
p = lutil_strcopy( p, ",cn=" );
p = lutil_strncopy( p, realm, rlen );
realm[-1] = '@';
} else if( user_realm && *user_realm ) {
p = lutil_strcopy( p, ",cn=" );
p = lutil_strcopy( p, user_realm );
p = lutil_strncopy( p, realm.bv_val, realm.bv_len );
}
if( mech->bv_len ) {

View File

@ -89,6 +89,75 @@ int slap_sasl_setpolicy( const char *arg )
return rc;
}
int slap_parse_user( struct berval *id, struct berval *user,
struct berval *realm, struct berval *mech )
{
char u;
assert( id );
assert( id->bv_val );
assert( user );
assert( realm );
assert( mech );
u = id->bv_val[ 0 ];
assert( u == 'u' || u == 'U' );
user->bv_val = strrchr( id->bv_val, ':' );
if ( user->bv_val == NULL ) {
return LDAP_PROTOCOL_ERROR;
}
user->bv_val[ 0 ] = '\0';
user->bv_val++;
user->bv_len = id->bv_len - ( user->bv_val - id->bv_val );
realm->bv_val = strchr( id->bv_val, '/' );
if ( realm->bv_val != NULL ) {
realm->bv_val[ 0 ] = '\0';
realm->bv_val++;
realm->bv_len = user->bv_val - realm->bv_val - 1;
}
mech->bv_val = strchr( id->bv_val, '.' );
if ( mech->bv_val != NULL ) {
mech->bv_val[ 0 ] = '\0';
mech->bv_val++;
if ( realm->bv_val ) {
mech->bv_len = realm->bv_val - mech->bv_val - 1;
} else {
mech->bv_len = user->bv_val - mech->bv_val - 1;
}
}
if ( id->bv_val[ 1 ] != '\0' ) {
return LDAP_PROTOCOL_ERROR;
}
if ( mech->bv_val != NULL ) {
assert( mech->bv_val == id->bv_val + 2 );
memmove( mech->bv_val - 2, mech->bv_val, mech->bv_len + 1 );
mech->bv_val -= 2;
}
if ( realm->bv_val ) {
assert( realm->bv_val >= id->bv_val + 2 );
memmove( realm->bv_val - 2, realm->bv_val, realm->bv_len + 1 );
realm->bv_val -= 2;
}
if ( user->bv_val > id->bv_val + 2 ) {
user->bv_val -= 2;
user->bv_len += 2;
user->bv_val[ 0 ] = u;
user->bv_val[ 1 ] = ':';
}
return LDAP_SUCCESS;
}
static int slap_parseURI( Operation *op, struct berval *uri,
struct berval *base, struct berval *nbase,
int *scope, Filter **filter, struct berval *fstr )
@ -115,8 +184,8 @@ static int slap_parseURI( Operation *op, struct berval *uri,
"slap_parseURI: parsing %s\n", uri->bv_val, 0, 0 );
#endif
rc = LDAP_PROTOCOL_ERROR;
if ( !strncasecmp( uri->bv_val, "dn", sizeof( "dn" ) - 1 ) ) {
rc = LDAP_PROTOCOL_ERROR;
bv.bv_val = uri->bv_val + sizeof( "dn" ) - 1;
if ( bv.bv_val[ 0 ] == '.' ) {
@ -173,11 +242,46 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);
break;
}
return( rc );
return rc;
} else if ( !strncasecmp( uri->bv_val, "u:", sizeof( "u:" ) - 1 ) ) {
/* FIXME: I'll handle this later ... */
return LDAP_PROTOCOL_ERROR;
} else if ( ( uri->bv_val[ 0 ] == 'u' || uri->bv_val[ 0 ] == 'U' )
&& ( uri->bv_val[ 1 ] == ':'
|| uri->bv_val[ 1 ] == '/'
|| uri->bv_val[ 1 ] == '.' ) )
{
Connection c = *op->o_conn;
char buf[ SLAP_LDAPDN_MAXLEN ];
struct berval id = { uri->bv_len, (char *)buf },
user = { 0, NULL },
realm = { 0, NULL },
mech = { 0, NULL };
if ( sizeof( buf ) <= uri->bv_len ) {
return LDAP_INVALID_SYNTAX;
}
strncpy( buf, uri->bv_val, sizeof( buf ) );
rc = slap_parse_user( &id, &user, &realm, &mech );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
if ( mech.bv_val ) {
c.c_sasl_bind_mech = mech;
} else {
c.c_sasl_bind_mech.bv_val = "AUTHZ";
c.c_sasl_bind_mech.bv_len = sizeof( "AUTHZ" ) - 1;
}
rc = slap_sasl_getdn( &c, op, user.bv_val, user.bv_len,
realm.bv_val, nbase, SLAP_GETDN_AUTHZID );
if ( rc == LDAP_SUCCESS ) {
*scope = LDAP_X_SCOPE_EXACT;
}
return rc;
}
rc = ldap_url_parse( uri->bv_val, &ludp );
@ -433,10 +537,10 @@ static int sasl_sc_sasl2dn( Operation *o, SlapReply *rs )
#ifdef NEW_LOGGING
LDAP_LOG( TRANSPORT, DETAIL1,
"slap_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
"slap_sc_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"slap_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
"slap_sc_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
#endif
return -1;
}

View File

@ -289,21 +289,26 @@ int slap_entry2mods( Entry *e, Modifications **mods, const char **text,
volatile sig_atomic_t slapd_abrupt_shutdown;
int slap_mods_check( Modifications *ml, int update, const char **text,
char *textbuf, size_t textlen, void *ctx )
char *textbuf, size_t textlen, void *ctx )
{
return -1;
}
int slap_mods2entry( Modifications *mods, Entry **e, int repl_user,
int dup, const char **text, char *textbuf, size_t textlen )
int dup, const char **text, char *textbuf, size_t textlen )
{
return -1;
}
int slap_mods_opattrs( Operation *op, Modifications *mods,
Modifications **modtail, const char **text,
char *textbuf, size_t textlen )
Modifications **modtail, const char **text,
char *textbuf, size_t textlen )
{
return -1;
}
int slap_parse_user( struct berval *id, struct berval *user,
struct berval *realm, struct berval *mech )
{
return -1;
}