]> git.sur5r.net Git - openldap/commitdiff
saslAuthzTo/From stuff
authorPierangelo Masarati <ando@openldap.org>
Sat, 13 Dec 2003 23:02:59 +0000 (23:02 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 13 Dec 2003 23:02:59 +0000 (23:02 +0000)
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 '/'.

servers/slapd/controls.c
servers/slapd/proto-slap.h
servers/slapd/sasl.c
servers/slapd/saslauthz.c
servers/slapd/tools/mimic.c

index 8177fa38ea46e1715c1c855769c43a1c71f3589b..1433e1fef079acd680e8da28b7c47bd5b79094bd 100644 (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 };
+
+               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 );
+               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
index 67e5d4986d522711d29d9a34f358b2ad0cf1363f..86078658aededd4bc50bde737b5a5d7e1b894426 100644 (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,
index 3575c800443a818b0f2324bb90ab8b27f84ad9ca..4613cee59fab6055dc39701026b18ce892a61fea 100644 (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 );
-                       p = lutil_strcopy( p, ",cn=" );
-                       p = lutil_strncopy( p, realm, rlen );
-                       realm[-1] = '@';
-               } else if( user_realm && *user_realm ) {
+               if( realm.bv_len ) {
                        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 ) {
index 1c0ca2efab7de1dc3a3560c1705bee9fc8dd85dc..76e79c458bb47f01754c71b51e2b90a9c52a71ea 100644 (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;
        }
index 387eef2988dd5b686fd7fd5da7fe56522390df79..2c9cd1c364ef1e98e9f6f8b7138a31b3e72d54c3 100644 (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;
+}