mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
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:
parent
0d8613c274
commit
4602c935f7
@ -748,9 +748,30 @@ static int parseProxyAuthz (
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
/* 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 };
|
||||
|
||||
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,
|
||||
ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len,
|
||||
NULL, &dn, SLAP_GETDN_AUTHZID );
|
||||
user.bv_val, user.bv_len,
|
||||
realm.bv_val, &dn, SLAP_GETDN_AUTHZID );
|
||||
|
||||
if( rc != LDAP_SUCCESS || !dn.bv_len ) {
|
||||
if ( dn.bv_val ) {
|
||||
@ -759,6 +780,7 @@ static int parseProxyAuthz (
|
||||
rs->sr_text = "authzId mapping failed";
|
||||
return LDAP_PROXY_AUTHZ_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( OPERATION, RESULTS,
|
||||
|
@ -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,
|
||||
|
@ -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 ) {
|
||||
|
@ -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
|
||||
|
||||
if ( !strncasecmp( uri->bv_val, "dn", sizeof( "dn" ) - 1 ) ) {
|
||||
rc = LDAP_PROTOCOL_ERROR;
|
||||
if ( !strncasecmp( uri->bv_val, "dn", sizeof( "dn" ) - 1 ) ) {
|
||||
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;
|
||||
}
|
||||
|
@ -307,3 +307,8 @@ int slap_mods_opattrs( Operation *op, Modifications *mods,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int slap_parse_user( struct berval *id, struct berval *user,
|
||||
struct berval *realm, struct berval *mech )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user