+ struct berval val, bv;
+ ber_len_t i;
+ int rc = LDAP_SUCCESS;
+
+ assert( valp != NULL );
+
+ val = *valp;
+
+ /* check minimal size */
+ if ( val.bv_len < STRLENOF( "{*}" ) ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ val.bv_len--;
+
+ /* check SEQUENCE boundaries */
+ if ( val.bv_val[ 0 ] != '{' /*}*/ ||
+ val.bv_val[ val.bv_len ] != /*{*/ '}' )
+ {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ /* extract and check OID */
+ for ( i = 1; i < val.bv_len; i++ ) {
+ if ( !ASCII_SPACE( val.bv_val[ i ] ) ) {
+ break;
+ }
+ }
+
+ bv.bv_val = &val.bv_val[ i ];
+
+ for ( i++; i < val.bv_len; i++ ) {
+ if ( ASCII_SPACE( val.bv_val[ i ] ) )
+ {
+ break;
+ }
+ }
+
+ bv.bv_len = &val.bv_val[ i ] - bv.bv_val;
+
+ rc = numericoidValidate( NULL, &bv );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ if ( i == val.bv_len ) {
+ return LDAP_SUCCESS;
+ }
+
+ if ( val.bv_val[ i ] != ' ' ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ for ( i++; i < val.bv_len; i++ ) {
+ if ( !ASCII_SPACE( val.bv_val[ i ] ) ) {
+ break;
+ }
+ }
+
+ if ( i == val.bv_len ) {
+ return LDAP_SUCCESS;
+ }
+
+ /* extract and check criticality */
+ if ( strncasecmp( &val.bv_val[ i ], "criticality ", STRLENOF( "criticality " ) ) == 0 )
+ {
+ i += STRLENOF( "criticality " );
+ for ( ; i < val.bv_len; i++ ) {
+ if ( !ASCII_SPACE( val.bv_val[ i ] ) ) {
+ break;
+ }
+ }
+
+ if ( i == val.bv_len ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ bv.bv_val = &val.bv_val[ i ];
+
+ for ( ; i < val.bv_len; i++ ) {
+ if ( ASCII_SPACE( val.bv_val[ i ] ) ) {
+ break;
+ }
+ }
+
+ bv.bv_len = &val.bv_val[ i ] - bv.bv_val;
+
+ if ( !bvmatch( &bv, &slap_true_bv ) && !bvmatch( &bv, &slap_false_bv ) )
+ {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ if ( i == val.bv_len ) {
+ return LDAP_SUCCESS;
+ }
+
+ if ( val.bv_val[ i ] != ' ' ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ for ( i++; i < val.bv_len; i++ ) {
+ if ( !ASCII_SPACE( val.bv_val[ i ] ) ) {
+ break;
+ }
+ }
+
+ if ( i == val.bv_len ) {
+ return LDAP_SUCCESS;
+ }
+ }
+
+ /* extract and check controlValue */
+ if ( strncasecmp( &val.bv_val[ i ], "controlValue ", STRLENOF( "controlValue " ) ) == 0 )
+ {
+ ber_len_t valueStart, valueLen;
+
+ i += STRLENOF( "controlValue " );
+ for ( ; i < val.bv_len; i++ ) {
+ if ( !ASCII_SPACE( val.bv_val[ i ] ) ) {
+ break;
+ }
+ }
+
+ if ( i == val.bv_len ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ if ( val.bv_val[ i ] != '"' ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ i++;
+ valueStart = i;
+
+ for ( ; i < val.bv_len; i++ ) {
+ if ( val.bv_val[ i ] == '"' ) {
+ break;
+ }
+
+ if ( !ASCII_HEX( val.bv_val[ i ] ) ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+ }
+
+ if ( val.bv_val[ i ] != '"' ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ valueLen = i - valueStart;
+ if ( (valueLen/2)*2 != valueLen ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ for ( i++; i < val.bv_len; i++ ) {
+ if ( !ASCII_SPACE( val.bv_val[ i ] ) ) {
+ break;
+ }
+ }
+
+ if ( i == val.bv_len ) {
+ return LDAP_SUCCESS;
+ }
+ }
+
+ return LDAP_INVALID_SYNTAX;
+}
+
+static int
+accesslog_ctrls(
+ LDAPControl **ctrls,
+ BerVarray *valsp,
+ BerVarray *nvalsp,
+ void *memctx )
+{
+ long i, rc = 0;