+
+ } else if ( strcasecmp( argv[ 0 ], "tls" ) == 0 ) {
+ unsigned *flagsp = mi->mi_ntargets ?
+ &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags
+ : &mi->mi_flags;
+
+ if ( argc != 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"tls <what>\" needs 1 argument.\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ /* start */
+ if ( strcasecmp( argv[ 1 ], "start" ) == 0 ) {
+ *flagsp |= ( LDAP_BACK_F_USE_TLS | LDAP_BACK_F_TLS_CRITICAL );
+
+ /* try start tls */
+ } else if ( strcasecmp( argv[ 1 ], "try-start" ) == 0 ) {
+ *flagsp &= ~LDAP_BACK_F_TLS_CRITICAL;
+ *flagsp |= LDAP_BACK_F_USE_TLS;
+
+ /* propagate start tls */
+ } else if ( strcasecmp( argv[ 1 ], "propagate" ) == 0 ) {
+ *flagsp |= ( LDAP_BACK_F_PROPAGATE_TLS | LDAP_BACK_F_TLS_CRITICAL );
+
+ /* try start tls */
+ } else if ( strcasecmp( argv[ 1 ], "try-propagate" ) == 0 ) {
+ *flagsp &= ~LDAP_BACK_F_TLS_CRITICAL;
+ *flagsp |= LDAP_BACK_F_PROPAGATE_TLS;
+
+ } else {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"tls <what>\": unknown argument \"%s\".\n",
+ fname, lineno, argv[ 1 ] );
+ return( 1 );
+ }
+
+ } else if ( strcasecmp( argv[ 0 ], "t-f-support" ) == 0 ) {
+ unsigned *flagsp = mi->mi_ntargets ?
+ &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags
+ : &mi->mi_flags;
+
+ if ( argc != 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"t-f-support {FALSE|true|discover}\" needs 1 argument.\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ switch ( check_true_false( argv[ 1 ] ) ) {
+ case 0:
+ *flagsp &= ~LDAP_BACK_F_T_F_MASK2;
+ break;
+
+ case 1:
+ *flagsp |= LDAP_BACK_F_T_F;
+ break;
+
+ default:
+ if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
+ *flagsp |= LDAP_BACK_F_T_F_DISCOVER;
+
+ } else {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n",
+ fname, lineno, argv[ 1 ] );
+ return 1;
+ }
+ break;
+ }
+
+ /* onerr? */
+ } else if ( strcasecmp( argv[ 0 ], "onerr" ) == 0 ) {
+ if ( argc != 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"onerr {CONTINUE|report|stop}\" takes 1 argument\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ if ( strcasecmp( argv[ 1 ], "continue" ) == 0 ) {
+ mi->mi_flags &= ~META_BACK_F_ONERR_MASK;
+
+ } else if ( strcasecmp( argv[ 1 ], "stop" ) == 0 ) {
+ mi->mi_flags |= META_BACK_F_ONERR_STOP;
+
+ } else if ( strcasecmp( argv[ 1 ], "report" ) == 0 ) {
+ mi->mi_flags |= META_BACK_F_ONERR_REPORT;
+
+ } else {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"onerr {CONTINUE|report|stop}\": invalid arg \"%s\".\n",
+ fname, lineno, argv[ 1 ] );
+ return 1;
+ }
+
+ /* bind-defer? */
+ } else if ( strcasecmp( argv[ 0 ], "pseudoroot-bind-defer" ) == 0
+ || strcasecmp( argv[ 0 ], "root-bind-defer" ) == 0 )
+ {
+ if ( argc != 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"[pseudo]root-bind-defer {TRUE|false}\" takes 1 argument\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ switch ( check_true_false( argv[ 1 ] ) ) {
+ case 0:
+ mi->mi_flags &= ~META_BACK_F_DEFER_ROOTDN_BIND;
+ break;
+
+ case 1:
+ mi->mi_flags |= META_BACK_F_DEFER_ROOTDN_BIND;
+ break;
+
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"[pseudo]root-bind-defer {TRUE|false}\": invalid arg \"%s\".\n",
+ fname, lineno, argv[ 1 ] );
+ return 1;
+ }
+
+ /* single-conn? */
+ } else if ( strcasecmp( argv[ 0 ], "single-conn" ) == 0 ) {
+ if ( argc != 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"single-conn {FALSE|true}\" takes 1 argument\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ if ( mi->mi_ntargets > 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"single-conn\" must appear before target definitions\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ switch ( check_true_false( argv[ 1 ] ) ) {
+ case 0:
+ mi->mi_flags &= ~LDAP_BACK_F_SINGLECONN;
+ break;
+
+ case 1:
+ mi->mi_flags |= LDAP_BACK_F_SINGLECONN;
+ break;
+
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"single-conn {FALSE|true}\": invalid arg \"%s\".\n",
+ fname, lineno, argv[ 1 ] );
+ return 1;
+ }
+
+ /* use-temporaries? */
+ } else if ( strcasecmp( argv[ 0 ], "use-temporary-conn" ) == 0 ) {
+ if ( argc != 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"use-temporary-conn {FALSE|true}\" takes 1 argument\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ if ( mi->mi_ntargets > 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"use-temporary-conn\" must appear before target definitions\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ switch ( check_true_false( argv[ 1 ] ) ) {
+ case 0:
+ mi->mi_flags &= ~LDAP_BACK_F_USE_TEMPORARIES;
+ break;
+
+ case 1:
+ mi->mi_flags |= LDAP_BACK_F_USE_TEMPORARIES;
+ break;
+
+ default:
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"use-temporary-conn {FALSE|true}\": invalid arg \"%s\".\n",
+ fname, lineno, argv[ 1 ] );
+ return 1;
+ }
+
+ /* privileged connections pool max size ? */
+ } else if ( strcasecmp( argv[ 0 ], "conn-pool-max" ) == 0 ) {
+ if ( argc != 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"conn-pool-max <n>\" takes 1 argument\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ if ( mi->mi_ntargets > 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"conn-pool-max\" must appear before target definitions\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ if ( lutil_atoi( &mi->mi_conn_priv_max, argv[1] )
+ || mi->mi_conn_priv_max < LDAP_BACK_CONN_PRIV_MIN
+ || mi->mi_conn_priv_max > LDAP_BACK_CONN_PRIV_MAX )
+ {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"conn-pool-max <n>\": invalid arg \"%s\".\n",
+ fname, lineno, argv[ 1 ] );
+ return 1;
+ }
+
+ } else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) {
+ unsigned flag = 0;
+ unsigned *flagsp = mi->mi_ntargets ?
+ &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags
+ : &mi->mi_flags;
+
+ if ( argc != 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"cancel {abandon|ignore|exop}\" takes 1 argument\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ if ( strcasecmp( argv[ 1 ], "abandon" ) == 0 ) {
+ flag = LDAP_BACK_F_CANCEL_ABANDON;
+
+ } else if ( strcasecmp( argv[ 1 ], "ignore" ) == 0 ) {
+ flag = LDAP_BACK_F_CANCEL_IGNORE;
+
+ } else if ( strcasecmp( argv[ 1 ], "exop" ) == 0 ) {
+ flag = LDAP_BACK_F_CANCEL_EXOP;
+
+ } else if ( strcasecmp( argv[ 1 ], "exop-discover" ) == 0 ) {
+ flag = LDAP_BACK_F_CANCEL_EXOP_DISCOVER;
+
+ } else {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"cancel {abandon|ignore|exop[-discover]}\": unknown mode \"%s\" \n",
+ fname, lineno, argv[ 1 ] );
+ return( 1 );
+ }
+
+ *flagsp &= ~LDAP_BACK_F_CANCEL_MASK2;
+ *flagsp |= flag;
+
+ } else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) {
+ char *sep;
+ time_t *tv = mi->mi_ntargets ?
+ mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_timeout
+ : mi->mi_timeout;
+ int c;
+
+ if ( argc < 2 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: \"timeout [{add|bind|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n",
+ fname, lineno, 0 );
+ return( 1 );
+ }
+
+ for ( c = 1; c < argc; c++ ) {
+ time_t *t = NULL;
+ unsigned long val;
+
+ sep = strchr( argv[ c ], '=' );
+ if ( sep != NULL ) {
+ size_t len = sep - argv[ c ];
+
+ if ( strncasecmp( argv[ c ], "bind", len ) == 0 ) {
+ t = &tv[ SLAP_OP_BIND ];
+ /* unbind makes little sense */
+ } else if ( strncasecmp( argv[ c ], "add", len ) == 0 ) {
+ t = &tv[ SLAP_OP_ADD ];
+ } else if ( strncasecmp( argv[ c ], "delete", len ) == 0 ) {
+ t = &tv[ SLAP_OP_DELETE ];
+ } else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) {
+ t = &tv[ SLAP_OP_MODRDN ];
+ } else if ( strncasecmp( argv[ c ], "modify", len ) == 0 ) {
+ t = &tv[ SLAP_OP_MODIFY ];
+ } else if ( strncasecmp( argv[ c ], "compare", len ) == 0 ) {
+ t = &tv[ SLAP_OP_COMPARE ];
+ } else if ( strncasecmp( argv[ c ], "search", len ) == 0 ) {
+ t = &tv[ SLAP_OP_SEARCH ];
+ /* abandon makes little sense */
+#if 0 /* not implemented yet */
+ } else if ( strncasecmp( argv[ c ], "extended", len ) == 0 ) {
+ t = &tv[ SLAP_OP_EXTENDED ];
+#endif
+ } else {
+ char buf[ SLAP_TEXT_BUFLEN ];
+ snprintf( buf, sizeof( buf ),
+ "unknown/unhandled operation \"%s\" for timeout #%d",
+ argv[ c ], c - 1 );
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: %s.\n",
+ fname, lineno, buf );
+ return 1;
+ }
+ sep++;
+
+ } else {
+ sep = argv[ c ];
+ }
+
+ if ( lutil_parse_time( sep, &val ) != 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unable to parse value \"%s\" for timeout.\n",
+ fname, lineno, sep );
+ return 1;
+ }
+
+ if ( t ) {
+ *t = (time_t)val;
+
+ } else {
+ int i;
+
+ for ( i = 0; i < SLAP_OP_LAST; i++ ) {
+ tv[ i ] = (time_t)val;
+ }
+ }
+ }