+static char aclbuf[ACLBUF_MAXLEN];
+
+static char *
+dnaccess2text( slap_dn_access *bdn, char *ptr, int is_realdn )
+{
+ *ptr++ = ' ';
+
+ if ( is_realdn ) {
+ ptr = lutil_strcopy( ptr, "real" );
+ }
+
+ if ( ber_bvccmp( &bdn->a_pat, '*' ) ||
+ bdn->a_style == ACL_STYLE_ANONYMOUS ||
+ bdn->a_style == ACL_STYLE_USERS ||
+ bdn->a_style == ACL_STYLE_SELF )
+ {
+ if ( is_realdn ) {
+ assert( ! ber_bvccmp( &bdn->a_pat, '*' ) );
+ }
+
+ ptr = lutil_strcopy( ptr, bdn->a_pat.bv_val );
+ if ( bdn->a_style == ACL_STYLE_SELF && bdn->a_self_level != 0 ) {
+ int n = sprintf( ptr, ".level{%d}", bdn->a_self_level );
+ if ( n > 0 ) {
+ ptr += n;
+ } /* else ? */
+ }
+
+ } else {
+ ptr = lutil_strcopy( ptr, "dn." );
+ if ( bdn->a_style == ACL_STYLE_BASE )
+ ptr = lutil_strcopy( ptr, style_base );
+ else
+ ptr = lutil_strcopy( ptr, style_strings[bdn->a_style] );
+ if ( bdn->a_style == ACL_STYLE_LEVEL ) {
+ int n = sprintf( ptr, "{%d}", bdn->a_level );
+ if ( n > 0 ) {
+ ptr += n;
+ } /* else ? */
+ }
+ if ( bdn->a_expand ) {
+ ptr = lutil_strcopy( ptr, ",expand" );
+ }
+ *ptr++ = '=';
+ *ptr++ = '"';
+ ptr = lutil_strcopy( ptr, bdn->a_pat.bv_val );
+ *ptr++ = '"';
+ }
+ return ptr;
+}
+
+static char *
+access2text( Access *b, char *ptr )
+{
+ char maskbuf[ACCESSMASK_MAXLEN];
+
+ ptr = lutil_strcopy( ptr, "\tby" );
+
+ if ( !BER_BVISEMPTY( &b->a_dn_pat ) ) {
+ ptr = dnaccess2text( &b->a_dn, ptr, 0 );
+ }
+ if ( b->a_dn_at ) {
+ ptr = lutil_strcopy( ptr, " dnattr=" );
+ ptr = lutil_strcopy( ptr, b->a_dn_at->ad_cname.bv_val );
+ }
+
+ if ( !BER_BVISEMPTY( &b->a_realdn_pat ) ) {
+ ptr = dnaccess2text( &b->a_realdn, ptr, 1 );
+ }
+ if ( b->a_realdn_at ) {
+ ptr = lutil_strcopy( ptr, " realdnattr=" );
+ ptr = lutil_strcopy( ptr, b->a_realdn_at->ad_cname.bv_val );
+ }
+
+ if ( !BER_BVISEMPTY( &b->a_group_pat ) ) {
+ ptr = lutil_strcopy( ptr, " group/" );
+ ptr = lutil_strcopy( ptr, b->a_group_oc ?
+ b->a_group_oc->soc_cname.bv_val : SLAPD_GROUP_CLASS );
+ *ptr++ = '/';
+ ptr = lutil_strcopy( ptr, b->a_group_at ?
+ b->a_group_at->ad_cname.bv_val : SLAPD_GROUP_ATTR );
+ *ptr++ = '.';
+ ptr = lutil_strcopy( ptr, style_strings[b->a_group_style] );
+ *ptr++ = '=';
+ *ptr++ = '"';
+ ptr = lutil_strcopy( ptr, b->a_group_pat.bv_val );
+ *ptr++ = '"';
+ }
+
+ if ( !BER_BVISEMPTY( &b->a_peername_pat ) ) {
+ ptr = lutil_strcopy( ptr, " peername" );
+ *ptr++ = '.';
+ ptr = lutil_strcopy( ptr, style_strings[b->a_peername_style] );
+ *ptr++ = '=';
+ *ptr++ = '"';
+ ptr = lutil_strcopy( ptr, b->a_peername_pat.bv_val );
+ *ptr++ = '"';
+ }
+
+ if ( !BER_BVISEMPTY( &b->a_sockname_pat ) ) {
+ ptr = lutil_strcopy( ptr, " sockname" );
+ *ptr++ = '.';
+ ptr = lutil_strcopy( ptr, style_strings[b->a_sockname_style] );
+ *ptr++ = '=';
+ *ptr++ = '"';
+ ptr = lutil_strcopy( ptr, b->a_sockname_pat.bv_val );
+ *ptr++ = '"';
+ }
+
+ if ( !BER_BVISEMPTY( &b->a_domain_pat ) ) {
+ ptr = lutil_strcopy( ptr, " domain" );
+ *ptr++ = '.';
+ ptr = lutil_strcopy( ptr, style_strings[b->a_domain_style] );
+ if ( b->a_domain_expand ) {
+ ptr = lutil_strcopy( ptr, ",expand" );
+ }
+ *ptr++ = '=';
+ ptr = lutil_strcopy( ptr, b->a_domain_pat.bv_val );
+ }
+
+ if ( !BER_BVISEMPTY( &b->a_sockurl_pat ) ) {
+ ptr = lutil_strcopy( ptr, " sockurl" );
+ *ptr++ = '.';
+ ptr = lutil_strcopy( ptr, style_strings[b->a_sockurl_style] );
+ *ptr++ = '=';
+ *ptr++ = '"';
+ ptr = lutil_strcopy( ptr, b->a_sockurl_pat.bv_val );
+ *ptr++ = '"';
+ }
+
+ if ( !BER_BVISEMPTY( &b->a_set_pat ) ) {
+ ptr = lutil_strcopy( ptr, " set" );
+ *ptr++ = '.';
+ ptr = lutil_strcopy( ptr, style_strings[b->a_set_style] );
+ *ptr++ = '=';
+ *ptr++ = '"';
+ ptr = lutil_strcopy( ptr, b->a_set_pat.bv_val );
+ *ptr++ = '"';
+ }
+
+#ifdef SLAP_DYNACL
+ if ( b->a_dynacl ) {
+ slap_dynacl_t *da;
+
+ for ( da = b->a_dynacl; da; da = da->da_next ) {
+ if ( da->da_unparse ) {
+ struct berval bv = BER_BVNULL;
+ (void)( *da->da_unparse )( da->da_private, &bv );
+ assert( !BER_BVISNULL( &bv ) );
+ ptr = lutil_strcopy( ptr, bv.bv_val );
+ ch_free( bv.bv_val );
+ }
+ }
+ }
+#endif /* SLAP_DYNACL */
+
+ /* Security Strength Factors */
+ if ( b->a_authz.sai_ssf ) {
+ ptr += sprintf( ptr, " ssf=%u",
+ b->a_authz.sai_ssf );
+ }
+ if ( b->a_authz.sai_transport_ssf ) {
+ ptr += sprintf( ptr, " transport_ssf=%u",
+ b->a_authz.sai_transport_ssf );
+ }
+ if ( b->a_authz.sai_tls_ssf ) {
+ ptr += sprintf( ptr, " tls_ssf=%u",
+ b->a_authz.sai_tls_ssf );
+ }
+ if ( b->a_authz.sai_sasl_ssf ) {
+ ptr += sprintf( ptr, " sasl_ssf=%u",
+ b->a_authz.sai_sasl_ssf );
+ }
+
+ *ptr++ = ' ';
+ if ( b->a_dn_self ) {
+ ptr = lutil_strcopy( ptr, "self" );
+ } else if ( b->a_realdn_self ) {
+ ptr = lutil_strcopy( ptr, "realself" );
+ }
+ ptr = lutil_strcopy( ptr, accessmask2str( b->a_access_mask, maskbuf, 0 ));
+ if ( !maskbuf[0] ) ptr--;
+
+ if( b->a_type == ACL_BREAK ) {
+ ptr = lutil_strcopy( ptr, " break" );
+
+ } else if( b->a_type == ACL_CONTINUE ) {
+ ptr = lutil_strcopy( ptr, " continue" );
+
+ } else if( b->a_type != ACL_STOP ) {
+ ptr = lutil_strcopy( ptr, " unknown-control" );
+ } else {
+ if ( !maskbuf[0] ) ptr = lutil_strcopy( ptr, " stop" );
+ }
+ *ptr++ = '\n';
+
+ return ptr;
+}
+
+void
+acl_unparse( AccessControl *a, struct berval *bv )