]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/saslauthz.c
ITS#2895 store a copy in the entry cache
[openldap] / servers / slapd / saslauthz.c
index 8eb69e8318231413e92d3cf6e148fe4cf41d6e1b..78bb9ea7d832cf86dc37dd029bcc01b5b275319b 100644 (file)
@@ -72,9 +72,10 @@ static int nSaslRegexp = 0;
 static SaslRegexp_t *SaslRegexp = NULL;
 
 /* What SASL proxy authorization policies are allowed? */
-#define        SASL_AUTHZ_NONE 0
-#define        SASL_AUTHZ_FROM 1
-#define        SASL_AUTHZ_TO   2
+#define        SASL_AUTHZ_NONE 0x00
+#define        SASL_AUTHZ_FROM 0x01
+#define        SASL_AUTHZ_TO   0x02
+#define SASL_AUTHZ_AND 0x10
 
 static int authz_policy = SASL_AUTHZ_NONE;
 
@@ -88,8 +89,10 @@ int slap_sasl_setpolicy( const char *arg )
                authz_policy = SASL_AUTHZ_FROM;
        } else if ( strcasecmp( arg, "to" ) == 0 ) {
                authz_policy = SASL_AUTHZ_TO;
-       } else if ( strcasecmp( arg, "both" ) == 0 ) {
+       } else if ( strcasecmp( arg, "both" ) == 0 || strcasecmp( arg, "any" ) == 0 ) {
                authz_policy = SASL_AUTHZ_FROM | SASL_AUTHZ_TO;
+       } else if ( strcasecmp( arg, "all" ) == 0 ) {
+               authz_policy = SASL_AUTHZ_FROM | SASL_AUTHZ_TO | SASL_AUTHZ_AND;
        } else {
                rc = LDAP_OTHER;
        }
@@ -109,7 +112,10 @@ int slap_parse_user( struct berval *id, struct berval *user,
 
        u = id->bv_val[ 0 ];
        
-       assert( u == 'u' || u == 'U' );
+       if ( u != 'u' && u != 'U' ) {
+               /* called with something other than u: */
+               return LDAP_PROTOCOL_ERROR;
+       }
 
        /* uauthzid form:
         *              u[.mech[/realm]]:user
@@ -128,9 +134,11 @@ int slap_parse_user( struct berval *id, struct berval *user,
                mech->bv_val[ 0 ] = '\0';
                mech->bv_val++;
 
-               realm->bv_val = strchr( id->bv_val, '/' );
+               realm->bv_val = strchr( mech->bv_val, '/' );
 
                if ( realm->bv_val ) {
+                       realm->bv_val[ 0 ] = '\0';
+                       realm->bv_val++;
                        mech->bv_len = realm->bv_val - mech->bv_val - 1;
                        realm->bv_len = user->bv_val - realm->bv_val - 1;
                } else {
@@ -159,12 +167,11 @@ int slap_parse_user( struct berval *id, struct berval *user,
                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 ] = ':';
-       }
+       /* leave "u:" before user */
+       user->bv_val -= 2;
+       user->bv_len += 2;
+       user->bv_val[ 0 ] = u;
+       user->bv_val[ 1 ] = ':';
 
        return LDAP_SUCCESS;
 }
@@ -262,7 +269,7 @@ is_dn:              bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);
        {
                Connection      c = *op->o_conn;
                char            buf[ SLAP_LDAPDN_MAXLEN ];
-               struct berval   id = { uri->bv_len, (char *)buf },
+               struct berval   id,
                                user = { 0, NULL },
                                realm = { 0, NULL },
                                mech = { 0, NULL };
@@ -271,6 +278,8 @@ is_dn:              bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);
                        return LDAP_INVALID_SYNTAX;
                }
 
+               id.bv_len = uri->bv_len;
+               id.bv_val = buf;
                strncpy( buf, uri->bv_val, sizeof( buf ) );
 
                rc = slap_parse_user( &id, &user, &realm, &mech );
@@ -483,7 +492,8 @@ static void slap_sasl_rx_exp(
    LDAP URI to find the matching LDAP entry, using the pattern matching
    strings given in the saslregexp config file directive(s) */
 
-static int slap_sasl_regexp( struct berval *in, struct berval *out, void *ctx )
+static int slap_sasl_regexp( struct berval *in, struct berval *out,
+               int flags, void *ctx )
 {
        char *saslname = in->bv_val;
        SaslRegexp_t *reg;
@@ -638,7 +648,10 @@ exact_match:
                        goto exact_match;
 
                } else if ( d > 0 ) {
-                       struct berval bv = { op.o_req_ndn.bv_len, assertDN->bv_val + d };
+                       struct berval bv;
+
+                       bv.bv_len = op.o_req_ndn.bv_len;
+                       bv.bv_val = assertDN->bv_val + d;
 
                        if ( bv.bv_val[ -1 ] == ',' && dn_match( &op.o_req_ndn, &bv ) ) {
                                rc = LDAP_SUCCESS;
@@ -800,7 +813,7 @@ COMPLETE:
  * entry, return the DN of that one entry.
  */
 void slap_sasl2dn( Operation *opx,
-       struct berval *saslname, struct berval *sasldn )
+       struct berval *saslname, struct berval *sasldn, int flags )
 {
        int rc;
        slap_callback cb = { NULL, sasl_sc_sasl2dn, NULL, NULL };
@@ -823,7 +836,7 @@ void slap_sasl2dn( Operation *opx,
        cb.sc_private = sasldn;
 
        /* Convert the SASL name into a minimal URI */
-       if( !slap_sasl_regexp( saslname, &regout, opx->o_tmpmemctx ) ) {
+       if( !slap_sasl_regexp( saslname, &regout, flags, opx->o_tmpmemctx ) ) {
                goto FINISHED;
        }
 
@@ -855,6 +868,7 @@ void slap_sasl2dn( Operation *opx,
 
        case LDAP_SCOPE_ONELEVEL:
        case LDAP_SCOPE_SUBTREE:
+       case LDAP_SCOPE_SUBORDINATE:
                /* do a search */
                break;
 
@@ -962,7 +976,7 @@ int slap_sasl_authorized( Operation *op,
        if( authz_policy & SASL_AUTHZ_TO ) {
                rc = slap_sasl_check_authz( op, authcDN, authzDN,
                        slap_schema.si_ad_saslAuthzTo, authcDN );
-               if( rc == LDAP_SUCCESS ) {
+               if( rc == LDAP_SUCCESS && !(authz_policy & SASL_AUTHZ_AND) ) {
                        goto DONE;
                }
        }