]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-ldap/config.c
fix NOOP return code (ITS#4563; I'll check and confirm it later; NOOP support might...
[openldap] / servers / slapd / back-ldap / config.c
index ed5097518ca56d73f7ff21dfbf079f175c8e6d2f..02b475ca76fdaf1236c02cdfc6183fe4d4d19b12 100644 (file)
@@ -63,6 +63,9 @@ enum {
        LDAP_BACK_CFG_IDLE_TIMEOUT,
        LDAP_BACK_CFG_CONN_TTL,
        LDAP_BACK_CFG_NETWORK_TIMEOUT,
+       LDAP_BACK_CFG_VERSION,
+       LDAP_BACK_CFG_SINGLECONN,
+       LDAP_BACK_CFG_CANCEL,
        LDAP_BACK_CFG_REWRITE,
 
        LDAP_BACK_CFG_LAST
@@ -241,6 +244,30 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsDirectoryString "
                        "SINGLE-VALUE )",
                NULL, NULL },
+       { "protocol-version", "version", 2, 0, 0,
+               ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_VERSION,
+               ldap_back_cf_gen, "( OLcfgDbAt:3.18 "
+                       "NAME 'olcDbProtocolVersion' "
+                       "DESC 'protocol version' "
+                       "SYNTAX OMsInteger "
+                       "SINGLE-VALUE )",
+               NULL, NULL },
+       { "single-conn", "TRUE/FALSE", 2, 0, 0,
+               ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_SINGLECONN,
+               ldap_back_cf_gen, "( OLcfgDbAt:3.19 "
+                       "NAME 'olcDbSingleConn' "
+                       "DESC 'cache a single connection per identity' "
+                       "SYNTAX OMsBoolean "
+                       "SINGLE-VALUE )",
+               NULL, NULL },
+       { "cancel", "ABANDON|ignore|exop", 2, 0, 0,
+               ARG_MAGIC|LDAP_BACK_CFG_CANCEL,
+               ldap_back_cf_gen, "( OLcfgDbAt:3.20 "
+                       "NAME 'olcDbCancel' "
+                       "DESC 'abandon/ignore/exop operations when appropriate' "
+                       "SYNTAX OMsDirectoryString "
+                       "SINGLE-VALUE )",
+               NULL, NULL },
        { "suffixmassage", "[virtual]> <real", 2, 3, 0,
                ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
                ldap_back_cf_gen, NULL, NULL, NULL },
@@ -275,6 +302,8 @@ static ConfigOCs ldapocs[] = {
                        "$ olcDbProxyWhoAmI "
                        "$ olcDbTimeout "
                        "$ olcDbIdleTimeout "
+                       "$ olcDbSingleConn "
+                       "$ olcDbCancel "
                ") )",
                        Cft_Database, ldapcfg},
        { NULL, 0, NULL }
@@ -298,12 +327,20 @@ static slap_verbmasks tls_mode[] = {
 };
 
 static slap_verbmasks t_f_mode[] = {
-       { BER_BVC( "yes" ),             LDAP_BACK_F_SUPPORT_T_F },
-       { BER_BVC( "discover" ),        LDAP_BACK_F_SUPPORT_T_F_DISCOVER },
+       { BER_BVC( "yes" ),             LDAP_BACK_F_T_F },
+       { BER_BVC( "discover" ),        LDAP_BACK_F_T_F_DISCOVER },
        { BER_BVC( "no" ),              LDAP_BACK_F_NONE },
        { BER_BVNULL,                   0 }
 };
 
+static slap_verbmasks cancel_mode[] = {
+       { BER_BVC( "ignore" ),          LDAP_BACK_F_CANCEL_IGNORE },
+       { BER_BVC( "exop" ),            LDAP_BACK_F_CANCEL_EXOP },
+       { BER_BVC( "exop-discover" ),   LDAP_BACK_F_CANCEL_EXOP_DISCOVER },
+       { BER_BVC( "abandon" ),         LDAP_BACK_F_CANCEL_ABANDON },
+       { BER_BVNULL,                   0 }
+};
+
 static slap_cf_aux_table timeout_table[] = {
        { BER_BVC("add="), 0 * sizeof( time_t ), 'u', 0, NULL },
        { BER_BVC("delete="), 1 * sizeof( time_t ), 'u', 0, NULL },
@@ -529,7 +566,7 @@ ldap_back_cf_gen( ConfigArgs *c )
                        break;
 
                case LDAP_BACK_CFG_T_F:
-                       enum_to_verb( t_f_mode, (li->li_flags & LDAP_BACK_F_SUPPORT_T_F_MASK), &bv );
+                       enum_to_verb( t_f_mode, (li->li_flags & LDAP_BACK_F_T_F_MASK2), &bv );
                        if ( BER_BVISNULL( &bv ) ) {
                                /* there's something wrong... */
                                assert( 0 );
@@ -612,6 +649,35 @@ ldap_back_cf_gen( ConfigArgs *c )
                        value_add_one( &c->rvalue_vals, &bv );
                        } break;
 
+               case LDAP_BACK_CFG_VERSION:
+                       if ( li->li_version == 0 ) {
+                               return 1;
+                       }
+
+                       c->value_int = li->li_version;
+                       break;
+
+               case LDAP_BACK_CFG_SINGLECONN:
+                       c->value_int = LDAP_BACK_SINGLECONN( li );
+                       break;
+
+               case LDAP_BACK_CFG_CANCEL: {
+                       slap_mask_t     mask = LDAP_BACK_F_CANCEL_MASK2;
+
+                       if ( LDAP_BACK_CANCEL_DISCOVER( li ) ) {
+                               mask &= ~LDAP_BACK_F_CANCEL_EXOP;
+                       }
+                       enum_to_verb( cancel_mode, (li->li_flags & mask), &bv );
+                       if ( BER_BVISNULL( &bv ) ) {
+                               /* there's something wrong... */
+                               assert( 0 );
+                               rc = 1;
+
+                       } else {
+                               value_add_one( &c->rvalue_vals, &bv );
+                       }
+                       } break;
+
                default:
                        /* FIXME: we need to handle all... */
                        assert( 0 );
@@ -680,6 +746,7 @@ ldap_back_cf_gen( ConfigArgs *c )
                case LDAP_BACK_CFG_CHASE:
                case LDAP_BACK_CFG_T_F:
                case LDAP_BACK_CFG_WHOAMI:
+               case LDAP_BACK_CFG_CANCEL:
                        rc = 1;
                        break;
 
@@ -698,7 +765,15 @@ ldap_back_cf_gen( ConfigArgs *c )
                        break;
 
                case LDAP_BACK_CFG_NETWORK_TIMEOUT:
-                       li->li_network_timeout;
+                       li->li_network_timeout = 0;
+                       break;
+
+               case LDAP_BACK_CFG_VERSION:
+                       li->li_version = 0;
+                       break;
+
+               case LDAP_BACK_CFG_SINGLECONN:
+                       li->li_flags &= ~LDAP_BACK_F_SINGLECONN;
                        break;
 
                default:
@@ -726,7 +801,7 @@ ldap_back_cf_gen( ConfigArgs *c )
                }
 
                /* PARANOID: DN and more are not required nor allowed */
-               urlrc = ldap_url_parselist_ext( &lud, c->argv[ 1 ], ", \t" );
+               urlrc = ldap_url_parselist_ext( &lud, c->argv[ 1 ], ", \t", LDAP_PVT_URL_PARSE_NONE );
                if ( urlrc != LDAP_URL_SUCCESS ) {
                        char    *why;
 
@@ -790,7 +865,7 @@ ldap_back_cf_gen( ConfigArgs *c )
                                                "host and port allowed "
                                                "in \"uri <uri>\" statement "
                                                "for uri #%d of \"%s\"",
-                                               i, c->value_string );
+                                               i, c->argv[ 1 ] );
                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
                        }
                }
@@ -1059,7 +1134,6 @@ done_url:;
 
        case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: {
                struct berval   bv;
-#ifdef SLAP_AUTHZ_SYNTAX
                struct berval   in;
                int             rc;
 
@@ -1072,9 +1146,6 @@ done_url:;
                        Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
                        return 1;
                }
-#else /* !SLAP_AUTHZ_SYNTAX */
-               ber_str2bv( c->argv[ 1 ], 0, 1, &bv );
-#endif /* !SLAP_AUTHZ_SYNTAX */
                ber_bvarray_add( &li->li_idassert_authz, &bv );
                } break;
 
@@ -1133,7 +1204,7 @@ done_url:;
                        } else if ( strncasecmp( c->argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 ) {
                                char    *argvi = c->argv[ i ] + STRLENOF( "flags=" );
                                char    **flags = ldap_str2charray( argvi, "," );
-                               int     j;
+                               int     j, err = 0;
 
                                if ( flags == NULL ) {
                                        snprintf( c->msg, sizeof( c->msg ),
@@ -1145,6 +1216,7 @@ done_url:;
                                }
 
                                for ( j = 0; flags[ j ] != NULL; j++ ) {
+
                                        if ( strcasecmp( flags[ j ], "override" ) == 0 ) {
                                                li->li_idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
 
@@ -1161,9 +1233,12 @@ done_url:;
                                                                        "in \"idassert-mode <args>\" "
                                                                        "incompatible with previously issued \"obsolete-encoding-workaround\" flag.\n",
                                                                        c->fname, c->lineno, 0 );
-                                                       return 1;
+                                                       err = 1;
+                                                       break;
+
+                                               } else {
+                                                       li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ;
                                                }
-                                               li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ;
 
                                        } else if ( strcasecmp( flags[ j ], "obsolete-encoding-workaround" ) == 0 ) {
                                                if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
@@ -1172,9 +1247,12 @@ done_url:;
                                                                "in \"idassert-mode <args>\" "
                                                                "incompatible with previously issued \"obsolete-proxy-authz\" flag.\n",
                                                                c->fname, c->lineno, 0 );
-                                                       return 1;
+                                                       err = 1;
+                                                       break;
+
+                                               } else {
+                                                       li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND;
                                                }
-                                               li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND;
 
                                        } else {
                                                snprintf( c->msg, sizeof( c->msg ),
@@ -1182,12 +1260,15 @@ done_url:;
                                                        "unknown flag \"%s\"",
                                                        flags[ j ] );
                                                Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
-                                               ldap_charray_free( flags );
-                                               return 1;
+                                               err = 1;
+                                               break;
                                        }
                                }
 
                                ldap_charray_free( flags );
+                               if ( err ) {
+                                       return 1;
+                               }
 
                        } else if ( bindconf_parse( c->argv[ i ], &li->li_idassert ) ) {
                                return 1;
@@ -1213,14 +1294,41 @@ done_url:;
                }
                break;
 
-       case LDAP_BACK_CFG_T_F:
+       case LDAP_BACK_CFG_T_F: {
+               slap_mask_t             mask;
+
                i = verb_to_mask( c->argv[1], t_f_mode );
                if ( BER_BVISNULL( &t_f_mode[i].word ) ) {
                        return 1;
                }
-               li->li_flags &= ~LDAP_BACK_F_SUPPORT_T_F_MASK;
-               li->li_flags |= t_f_mode[i].mask;
-               break;
+
+               mask = t_f_mode[i].mask;
+
+               if ( LDAP_BACK_ISOPEN( li )
+                       && mask == LDAP_BACK_F_T_F_DISCOVER
+                       && !LDAP_BACK_T_F( li ) )
+               {
+                       int             rc;
+
+                       if ( li->li_uri == NULL ) {
+                               snprintf( c->msg, sizeof( c->msg ),
+                                       "need URI to discover \"cancel\" support "
+                                       "in \"cancel exop-discover\"" );
+                               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+                               return 1;
+                       }
+
+                       rc = slap_discover_feature( li->li_uri, li->li_version,
+                                       slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
+                                       LDAP_FEATURE_ABSOLUTE_FILTERS );
+                       if ( rc == LDAP_COMPARE_TRUE ) {
+                               mask |= LDAP_BACK_F_T_F;
+                       }
+               }
+
+               li->li_flags &= ~LDAP_BACK_F_T_F_MASK2;
+               li->li_flags |= mask;
+               } break;
 
        case LDAP_BACK_CFG_WHOAMI:
                if ( c->argc == 1 || c->value_int ) {
@@ -1295,6 +1403,64 @@ done_url:;
                li->li_network_timeout = (time_t)t;
                } break;
 
+       case LDAP_BACK_CFG_VERSION:
+               if ( c->value_int != 0 && ( c->value_int < LDAP_VERSION_MIN || c->value_int > LDAP_VERSION_MAX ) ) {
+                       snprintf( c->msg, sizeof( c->msg ),
+                               "unsupported version \"%s\" "
+                               "in \"protocol-version <version>\"",
+                               c->argv[ 1 ] );
+                       Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+                       return 1;
+               }
+
+               li->li_version = c->value_int;
+               break;
+
+       case LDAP_BACK_CFG_SINGLECONN:
+               if ( c->value_int ) {
+                       li->li_flags |= LDAP_BACK_F_SINGLECONN;
+
+               } else {
+                       li->li_flags &= ~LDAP_BACK_F_SINGLECONN;
+               }
+               break;
+
+       case LDAP_BACK_CFG_CANCEL: {
+               slap_mask_t             mask;
+
+               i = verb_to_mask( c->argv[1], cancel_mode );
+               if ( BER_BVISNULL( &cancel_mode[i].word ) ) {
+                       return 1;
+               }
+
+               mask = cancel_mode[i].mask;
+
+               if ( LDAP_BACK_ISOPEN( li )
+                       && mask == LDAP_BACK_F_CANCEL_EXOP_DISCOVER
+                       && !LDAP_BACK_CANCEL( li ) )
+               {
+                       int             rc;
+
+                       if ( li->li_uri == NULL ) {
+                               snprintf( c->msg, sizeof( c->msg ),
+                                       "need URI to discover \"cancel\" support "
+                                       "in \"cancel exop-discover\"" );
+                               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+                               return 1;
+                       }
+
+                       rc = slap_discover_feature( li->li_uri, li->li_version,
+                                       slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
+                                       LDAP_EXOP_CANCEL );
+                       if ( rc == LDAP_COMPARE_TRUE ) {
+                               mask |= LDAP_BACK_F_CANCEL_EXOP;
+                       }
+               }
+
+               li->li_flags &= ~LDAP_BACK_F_CANCEL_MASK2;
+               li->li_flags |= mask;
+               } break;
+
        case LDAP_BACK_CFG_REWRITE:
                snprintf( c->msg, sizeof( c->msg ),
                        "rewrite/remap capabilities have been moved "