+ if ( strcasecmp( left, "set" ) == 0 ) {
+ switch ( sty ) {
+ /* deprecated */
+ case ACL_STYLE_REGEX:
+ Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL,
+ "%s: line %d: "
+ "deprecated set style "
+ "\"regex\" in <by> clause; "
+ "use \"expand\" instead.\n",
+ fname, lineno, 0 );
+ sty = ACL_STYLE_EXPAND;
+ /* FALLTHRU */
+
+ case ACL_STYLE_BASE:
+ case ACL_STYLE_EXPAND:
+ break;
+
+ default:
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "inappropriate style \"%s\" in by clause.\n",
+ fname, lineno, style );
+ goto fail;
+ }
+
+ if ( !BER_BVISEMPTY( &b->a_set_pat ) ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: set attribute already specified.\n",
+ fname, lineno, 0 );
+ goto fail;
+ }
+
+ if ( right == NULL || *right == '\0' ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: no set is defined.\n",
+ fname, lineno, 0 );
+ goto fail;
+ }
+
+ b->a_set_style = sty;
+ ber_str2bv( right, 0, 1, &b->a_set_pat );
+
+ continue;
+ }
+
+#ifdef SLAP_DYNACL
+ {
+ char *name = NULL,
+ *opts = NULL;
+
+#if 1 /* tolerate legacy "aci" <who> */
+ if ( strcasecmp( left, "aci" ) == 0 ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "undocumented deprecated \"aci\" directive "
+ "is superseded by \"dynacl/aci\".\n",
+ fname, lineno, 0 );
+ name = "aci";
+
+ } else
+#endif /* tolerate legacy "aci" <who> */
+ if ( strncasecmp( left, "dynacl/", STRLENOF( "dynacl/" ) ) == 0 ) {
+ name = &left[ STRLENOF( "dynacl/" ) ];
+ opts = strchr( name, '/' );
+ if ( opts ) {
+ opts[ 0 ] = '\0';
+ opts++;
+ }
+ }
+
+ if ( name ) {
+ if ( slap_dynacl_config( fname, lineno, b, name, opts, sty, right ) ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "unable to configure dynacl \"%s\".\n",
+ fname, lineno, name );
+ goto fail;
+ }
+
+ continue;
+ }
+ }
+#endif /* SLAP_DYNACL */
+
+ if ( strcasecmp( left, "ssf" ) == 0 ) {
+ if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "inappropriate style \"%s\" in by clause.\n",
+ fname, lineno, style );
+ goto fail;
+ }
+
+ if ( b->a_authz.sai_ssf ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: ssf attribute already specified.\n",
+ fname, lineno, 0 );
+ goto fail;
+ }
+
+ if ( right == NULL || *right == '\0' ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: no ssf is defined.\n",
+ fname, lineno, 0 );
+ goto fail;
+ }
+
+ if ( lutil_atou( &b->a_authz.sai_ssf, right ) != 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: unable to parse ssf value (%s).\n",
+ fname, lineno, right );
+ goto fail;
+ }
+
+ if ( !b->a_authz.sai_ssf ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: invalid ssf value (%s).\n",
+ fname, lineno, right );
+ goto fail;
+ }
+ continue;
+ }
+
+ if ( strcasecmp( left, "transport_ssf" ) == 0 ) {
+ if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "inappropriate style \"%s\" in by clause.\n",
+ fname, lineno, style );
+ goto fail;
+ }
+
+ if ( b->a_authz.sai_transport_ssf ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "transport_ssf attribute already specified.\n",
+ fname, lineno, 0 );
+ goto fail;
+ }
+
+ if ( right == NULL || *right == '\0' ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: no transport_ssf is defined.\n",
+ fname, lineno, 0 );
+ goto fail;
+ }
+
+ if ( lutil_atou( &b->a_authz.sai_transport_ssf, right ) != 0 ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "unable to parse transport_ssf value (%s).\n",
+ fname, lineno, right );
+ goto fail;
+ }
+
+ if ( !b->a_authz.sai_transport_ssf ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: invalid transport_ssf value (%s).\n",
+ fname, lineno, right );
+ goto fail;
+ }
+ continue;
+ }
+
+ if ( strcasecmp( left, "tls_ssf" ) == 0 ) {
+ if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "inappropriate style \"%s\" in by clause.\n",
+ fname, lineno, style );
+ goto fail;
+ }
+
+ if ( b->a_authz.sai_tls_ssf ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "tls_ssf attribute already specified.\n",
+ fname, lineno, 0 );
+ goto fail;
+ }
+
+ if ( right == NULL || *right == '\0' ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: no tls_ssf is defined\n",
+ fname, lineno, 0 );
+ goto fail;
+ }
+
+ if ( lutil_atou( &b->a_authz.sai_tls_ssf, right ) != 0 ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "unable to parse tls_ssf value (%s).\n",
+ fname, lineno, right );
+ goto fail;
+ }
+
+ if ( !b->a_authz.sai_tls_ssf ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: invalid tls_ssf value (%s).\n",
+ fname, lineno, right );
+ goto fail;
+ }
+ continue;
+ }
+
+ if ( strcasecmp( left, "sasl_ssf" ) == 0 ) {
+ if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "inappropriate style \"%s\" in by clause.\n",
+ fname, lineno, style );
+ goto fail;
+ }
+
+ if ( b->a_authz.sai_sasl_ssf ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "sasl_ssf attribute already specified.\n",
+ fname, lineno, 0 );
+ goto fail;
+ }
+
+ if ( right == NULL || *right == '\0' ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: no sasl_ssf is defined.\n",
+ fname, lineno, 0 );
+ goto fail;
+ }
+
+ if ( lutil_atou( &b->a_authz.sai_sasl_ssf, right ) != 0 ) {
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "unable to parse sasl_ssf value (%s).\n",
+ fname, lineno, right );
+ goto fail;
+ }
+
+ if ( !b->a_authz.sai_sasl_ssf ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: invalid sasl_ssf value (%s).\n",
+ fname, lineno, right );
+ goto fail;
+ }
+ continue;
+ }
+
+ if ( right != NULL ) {
+ /* unsplit */
+ right[-1] = '=';
+ }
+ break;
+ }
+
+ if ( i == argc || ( strcasecmp( left, "stop" ) == 0 ) ) {
+ /* out of arguments or plain stop */
+
+ ACL_PRIV_ASSIGN( b->a_access_mask, ACL_PRIV_ADDITIVE );
+ ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE);
+ b->a_type = ACL_STOP;
+
+ access_append( &a->acl_access, b );
+ continue;
+ }
+
+ if ( strcasecmp( left, "continue" ) == 0 ) {
+ /* plain continue */
+
+ ACL_PRIV_ASSIGN( b->a_access_mask, ACL_PRIV_ADDITIVE );
+ ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE);
+ b->a_type = ACL_CONTINUE;
+
+ access_append( &a->acl_access, b );
+ continue;
+ }
+
+ if ( strcasecmp( left, "break" ) == 0 ) {
+ /* plain continue */
+
+ ACL_PRIV_ASSIGN(b->a_access_mask, ACL_PRIV_ADDITIVE);
+ ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE);
+ b->a_type = ACL_BREAK;
+
+ access_append( &a->acl_access, b );
+ continue;