~ubuntu-branches/ubuntu/maverick/openldap/maverick-proposed

« back to all changes in this revision

Viewing changes to servers/slapd/acl.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug, Steve Langasek, Mathias Gug
  • Date: 2009-02-18 18:44:00 UTC
  • mfrom: (1.1.2 upstream) (0.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20090218184400-zw4mjse9eywt5566
Tags: 2.4.14-0ubuntu1
[ Steve Langasek ]
* New upstream version
  - Fixes a bug with the pcache overlay not returning cached entries
    (closes: #497697)
  - Update evolution-ntlm patch to apply to current Makefiles.
  - (tentatively) drop gnutls-ciphers, since this bug was reported to be
    fixed upstream in 2.4.8.  The fix applied in 2.4.8 didn't match the
    patch from the bug report, so this should be watched for regressions.
* Build against db4.7 instead of db4.2 at last!  Closes: #421946.
* Build with --disable-ndb, to avoid a misbuild when libmysqlclient is
  installed in the build environment.
* New patch, no-crlcheck-for-gnutls, to fix a build failure when using
  --with-tls=gnutls.

[ Mathias Gug ]
* Merge from debian unstable, remaining changes:
  - debian/apparmor-profile: add AppArmor profile
  - debian/slapd.postinst: Reload AA profile on configuration
  - updated debian/slapd.README.Debian for note on AppArmor
  - debian/control: Recommends apparmor >= 2.1+1075-0ubuntu6
  - debian/control: Conflicts with apparmor-profiles << 2.1+1075-0ubuntu4
    to make sure that if earlier version of apparmour-profiles gets
    installed it won't overwrite our profile.
  - Modify Maintainer value to match the DebianMaintainerField
    speficication.
  - follow ApparmorProfileMigration and force apparmor compalin mode on 
    some upgrades (LP: #203529)
  - debian/slapd.dirs: add etc/apparmor.d/force-complain
  - debian/slapd.preinst: create symlink for force-complain on pre-feisty
    upgrades, upgrades where apparmor-profiles profile is unchanged (ie
    non-enforcing) and upgrades where apparmor profile does not exist.
  - debian/slapd.postrm: remove symlink in force-complain/ on purge
  - debian/patches/fix-ucred-libc due to changes how newer glibc handle
    the ucred struct now.
  - debian/control:
    - Build-depend on libltdl7-dev rather then libltdl3-dev.
  - debian/patches/autogen.sh:
    - Call libtoolize with the --install option to install config.{guess,sub}
      files.
  - Don't use local statement in config script as it fails if /bin/sh
    points to bash (LP: #286063).
  - Disable the testsuite on hppa. Allows building of packages on this
    architecture again, once this package is in the archive.
    LP: #288908.
  - debian/slapd.postinst, debian/slapd.script-common: set correct ownership
    and permissions on /var/lib/ldap, /etc/ldap/slapd.d (group readable) and
    /var/run/slapd (world readable). (LP: #257667).
  - debian/patches/nssov-build, debian/rules: 
    Build and package the nss overlay.
    debian/schema/misc.ldif: add ldif file for the misc schema, which defines
    rfc822MailMember (required by the nss overlay).
  - debian/{control,rules}: enable PIE hardening
  - Use cn=config as the default configuration backend instead of 
    slapd.conf. Migrate slapd.conf  file to /etc/ldap/slapd.d/ on upgrade
    asking the end user to enter a new password to control the access to the
    cn=config tree.
* debian/patches/corrupt-contextCSN: The contextCSN can get corrupted at
  times. (ITS: #5947)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* acl.c - routines to parse and check acl's */
2
 
/* $OpenLDAP: pkg/ldap/servers/slapd/acl.c,v 1.303.2.16 2008/05/20 00:08:13 quanah Exp $ */
 
2
/* $OpenLDAP: pkg/ldap/servers/slapd/acl.c,v 1.303.2.22 2009/01/22 00:00:59 kurt Exp $ */
3
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
4
 *
5
 
 * Copyright 1998-2008 The OpenLDAP Foundation.
 
5
 * Copyright 1998-2009 The OpenLDAP Foundation.
6
6
 * All rights reserved.
7
7
 *
8
8
 * Redistribution and use in source and binary forms, with or without
52
52
        Operation *op, Entry *e,
53
53
        AttributeDescription *desc,
54
54
        struct berval *val,
55
 
        int nmatch, regmatch_t *matches,
 
55
        AclRegexMatches *matches,
56
56
        AccessControlState *state );
57
57
 
58
58
static slap_control_t slap_acl_mask(
60
60
        Operation *op, Entry *e,
61
61
        AttributeDescription *desc,
62
62
        struct berval *val,
63
 
        int nmatch,
64
 
        regmatch_t *matches,
 
63
        AclRegexMatches *matches,
65
64
        int count,
66
 
        AccessControlState *state );
 
65
        AccessControlState *state,
 
66
        slap_access_t access );
67
67
 
68
68
static int      regex_matches(
69
 
        struct berval *pat, char *str, char *buf,
70
 
        int nmatch, regmatch_t *matches);
 
69
        struct berval *pat, char *str,
 
70
        struct berval *dn_matches, struct berval *val_matches,
 
71
        AclRegexMatches *matches);
71
72
 
72
73
typedef struct AclSetCookie {
73
74
        SetCookie       asc_cookie;
75
76
        Entry           *asc_e;
76
77
} AclSetCookie;
77
78
 
 
79
 
78
80
SLAP_SET_GATHER acl_set_gather;
79
81
SLAP_SET_GATHER acl_set_gather2;
80
82
 
115
117
        return 1;
116
118
}
117
119
 
 
120
#define MATCHES_DNMAXCOUNT(m)                                   \
 
121
        ( sizeof ( (m)->dn_data ) / sizeof( *(m)->dn_data ) )
 
122
#define MATCHES_VALMAXCOUNT(m)                                  \
 
123
        ( sizeof ( (m)->val_data ) / sizeof( *(m)->val_data ) )
 
124
#define MATCHES_MEMSET(m) do {                                  \
 
125
        memset( (m)->dn_data, '\0', sizeof( (m)->dn_data ) );   \
 
126
        memset( (m)->val_data, '\0', sizeof( (m)->val_data ) ); \
 
127
        (m)->dn_count = MATCHES_DNMAXCOUNT( (m) );              \
 
128
        (m)->val_count = MATCHES_VALMAXCOUNT( (m) );            \
 
129
} while ( 0 /* CONSTCOND */ )
 
130
 
118
131
int
119
132
slap_access_allowed(
120
133
        Operation               *op,
136
149
        slap_control_t                  control;
137
150
        slap_access_t                   access_level;
138
151
        const char                      *attr;
139
 
        regmatch_t                      matches[MAXREMATCHES];
 
152
        AclRegexMatches                 matches;
 
153
        AccessControlState              acl_state = ACL_STATE_INIT;
140
154
 
141
155
        assert( op != NULL );
142
156
        assert( e != NULL );
178
192
        }
179
193
 
180
194
        /* use backend default access if no backend acls */
181
 
        if ( op->o_bd->be_acl == NULL ) {
 
195
        if ( op->o_bd->be_acl == NULL && frontendDB->be_acl == NULL ) {
182
196
                int     i;
183
197
 
184
198
                Debug( LDAP_DEBUG_ACL,
200
214
        ret = 0;
201
215
        control = ACL_BREAK;
202
216
 
203
 
        if ( state && state->as_vd_ad == desc ) {
 
217
        if ( state == NULL )
 
218
                state = &acl_state;
 
219
        if ( state->as_vd_ad == desc ) {
204
220
                a = state->as_vd_acl;
205
221
                count = state->as_vd_acl_count;
 
222
                if ( state->as_fe_done )
 
223
                        state->as_fe_done--;
 
224
        } else {
 
225
                state->as_vi_acl = NULL;
206
226
 
207
 
        } else {
208
 
                if ( state ) state->as_vi_acl = NULL;
209
227
                a = NULL;
210
228
                count = 0;
211
229
        }
 
230
        if ( a == NULL )
 
231
                state->as_fe_done = 0;
 
232
 
212
233
        ACL_PRIV_ASSIGN( mask, *maskp );
213
 
        memset( matches, '\0', sizeof( matches ) );
 
234
        MATCHES_MEMSET( &matches );
214
235
 
215
236
        while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
216
 
                MAXREMATCHES, matches, state ) ) != NULL )
 
237
                &matches, state ) ) != NULL )
217
238
        {
218
 
                int i;
219
 
 
220
 
                for ( i = 0; i < MAXREMATCHES && matches[i].rm_so > 0; i++ ) {
221
 
                        Debug( LDAP_DEBUG_ACL, "=> match[%d]: %d %d ", i,
222
 
                                (int)matches[i].rm_so, (int)matches[i].rm_eo );
223
 
                        if ( matches[i].rm_so <= matches[0].rm_eo ) {
224
 
                                int n;
225
 
                                for ( n = matches[i].rm_so; n < matches[i].rm_eo; n++ ) {
226
 
                                        Debug( LDAP_DEBUG_ACL, "%c", e->e_ndn[n], 0, 0 );
227
 
                                }
228
 
                        }
229
 
                        Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );
 
239
                int i; 
 
240
                int dnmaxcount = MATCHES_DNMAXCOUNT( &matches );
 
241
                int valmaxcount = MATCHES_VALMAXCOUNT( &matches );
 
242
                regmatch_t *dn_data = matches.dn_data;
 
243
                regmatch_t *val_data = matches.val_data;
 
244
 
 
245
                /* DN matches */
 
246
                for ( i = 0; i < dnmaxcount && dn_data[i].rm_eo > 0; i++ ) {
 
247
                        char *data = e->e_ndn;
 
248
 
 
249
                        Debug( LDAP_DEBUG_ACL, "=> match[dn%d]: %d %d ", i,
 
250
                                (int)dn_data[i].rm_so, 
 
251
                                (int)dn_data[i].rm_eo );
 
252
                        if ( dn_data[i].rm_so <= dn_data[0].rm_eo ) {
 
253
                                int n;
 
254
                                for ( n = dn_data[i].rm_so; 
 
255
                                      n < dn_data[i].rm_eo; n++ ) {
 
256
                                        Debug( LDAP_DEBUG_ACL, "%c", 
 
257
                                               data[n], 0, 0 );
 
258
                                }
 
259
                        }
 
260
                        Debug( LDAP_DEBUG_ACL, "\n", 0, 0, 0 );
 
261
                }
 
262
 
 
263
                /* val matches */
 
264
                for ( i = 0; i < valmaxcount && val_data[i].rm_eo > 0; i++ ) {
 
265
                        char *data = val->bv_val;
 
266
 
 
267
                        Debug( LDAP_DEBUG_ACL, "=> match[val%d]: %d %d ", i,
 
268
                                (int)val_data[i].rm_so, 
 
269
                                (int)val_data[i].rm_eo );
 
270
                        if ( val_data[i].rm_so <= val_data[0].rm_eo ) {
 
271
                                int n;
 
272
                                for ( n = val_data[i].rm_so; 
 
273
                                      n < val_data[i].rm_eo; n++ ) {
 
274
                                        Debug( LDAP_DEBUG_ACL, "%c", 
 
275
                                               data[n], 0, 0 );
 
276
                                }
 
277
                        }
 
278
                        Debug( LDAP_DEBUG_ACL, "\n", 0, 0, 0 );
230
279
                }
231
280
 
232
281
                if ( state ) {
246
295
                }
247
296
 
248
297
                control = slap_acl_mask( a, &mask, op,
249
 
                        e, desc, val, MAXREMATCHES, matches, count, state );
 
298
                        e, desc, val, &matches, count, state, access );
250
299
 
251
300
                if ( control != ACL_BREAK ) {
252
301
                        break;
253
302
                }
254
303
 
255
 
                memset( matches, '\0', sizeof( matches ) );
 
304
                MATCHES_MEMSET( &matches );
256
305
        }
257
306
 
258
307
        if ( ACL_IS_INVALID( mask ) ) {
464
513
        Entry           *e,
465
514
        AttributeDescription *desc,
466
515
        struct berval   *val,
467
 
        int                     nmatch,
468
 
        regmatch_t      *matches,
 
516
        AclRegexMatches *matches,
469
517
        AccessControlState *state )
470
518
{
471
519
        const char *attr;
472
 
        int dnlen, patlen;
 
520
        ber_len_t dnlen;
473
521
        AccessControl *prev;
474
522
 
475
523
        assert( e != NULL );
476
524
        assert( count != NULL );
477
525
        assert( desc != NULL );
 
526
        assert( state != NULL );
478
527
 
479
528
        attr = desc->ad_cname.bv_val;
480
529
 
481
530
        assert( attr != NULL );
482
531
 
483
532
        if( a == NULL ) {
484
 
                if( op->o_bd == NULL ) {
 
533
                if( op->o_bd == NULL || op->o_bd->be_acl == NULL ) {
485
534
                        a = frontendDB->be_acl;
486
535
                } else {
487
536
                        a = op->o_bd->be_acl;
489
538
                prev = NULL;
490
539
 
491
540
                assert( a != NULL );
492
 
 
 
541
                if ( a == frontendDB->be_acl )
 
542
                        state->as_fe_done = 1;
493
543
        } else {
494
544
                prev = a;
495
545
                a = a->acl_next;
497
547
 
498
548
        dnlen = e->e_nname.bv_len;
499
549
 
 
550
 retry:
500
551
        for ( ; a != NULL; prev = a, a = a->acl_next ) {
501
552
                (*count) ++;
502
553
 
 
554
                if ( a != frontendDB->be_acl && state->as_fe_done )
 
555
                        state->as_fe_done++;
 
556
 
503
557
                if ( a->acl_dn_pat.bv_len || ( a->acl_dn_style != ACL_STYLE_REGEX )) {
504
558
                        if ( a->acl_dn_style == ACL_STYLE_REGEX ) {
505
559
                                Debug( LDAP_DEBUG_ACL, "=> dnpat: [%d] %s nsub: %d\n", 
506
560
                                        *count, a->acl_dn_pat.bv_val, (int) a->acl_dn_re.re_nsub );
507
 
                                if (regexec(&a->acl_dn_re, e->e_ndn, nmatch, matches, 0))
 
561
                                if ( regexec ( &a->acl_dn_re, 
 
562
                                               e->e_ndn, 
 
563
                                               matches->dn_count, 
 
564
                                               matches->dn_data, 0 ) )
508
565
                                        continue;
509
566
 
510
567
                        } else {
 
568
                                ber_len_t patlen;
 
569
 
511
570
                                Debug( LDAP_DEBUG_ACL, "=> dn: [%d] %s\n", 
512
571
                                        *count, a->acl_dn_pat.bv_val, 0 );
513
572
                                patlen = a->acl_dn_pat.bv_len;
521
580
 
522
581
                                } else if ( a->acl_dn_style == ACL_STYLE_ONE ) {
523
582
                                        ber_len_t       rdnlen = 0;
524
 
                                        int             sep = 0;
 
583
                                        ber_len_t       sep = 0;
525
584
 
526
585
                                        if ( dnlen <= patlen )
527
586
                                                continue;
533
592
                                        }
534
593
 
535
594
                                        rdnlen = dn_rdnlen( NULL, &e->e_nname );
536
 
                                        if ( rdnlen != dnlen - patlen - sep )
 
595
                                        if ( rdnlen + patlen + sep != dnlen )
537
596
                                                continue;
538
597
 
539
598
                                } else if ( a->acl_dn_style == ACL_STYLE_SUBTREE ) {
556
615
                }
557
616
 
558
617
                if ( a->acl_attrs && !ad_inlist( desc, a->acl_attrs ) ) {
559
 
                        matches[0].rm_so = matches[0].rm_eo = -1;
 
618
                        matches->dn_data[0].rm_so = -1;
 
619
                        matches->dn_data[0].rm_eo = -1;
 
620
                        matches->val_data[0].rm_so = -1;
 
621
                        matches->val_data[0].rm_eo = -1;
560
622
                        continue;
561
623
                }
562
624
 
566
628
                                continue;
567
629
                        }
568
630
 
569
 
                        if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) {
 
631
                        if( !( state->as_recorded & ACL_STATE_RECORDED_VD )) {
570
632
                                state->as_recorded |= ACL_STATE_RECORDED_VD;
571
633
                                state->as_vd_acl = prev;
572
634
                                state->as_vd_acl_count = *count - 1;
576
638
                                Debug( LDAP_DEBUG_ACL,
577
639
                                        "acl_get: valpat %s\n",
578
640
                                        a->acl_attrval.bv_val, 0, 0 );
579
 
                                if ( regexec( &a->acl_attrval_re, val->bv_val, 0, NULL, 0 ) )
 
641
                                if ( regexec ( &a->acl_attrval_re, 
 
642
                                                    val->bv_val, 
 
643
                                                    matches->val_count, 
 
644
                                                    matches->val_data, 0 ) )
580
645
                                {
581
646
                                        continue;
582
647
                                }
596
661
                                                continue;
597
662
                                        
598
663
                                } else {
599
 
                                        int             patlen, vdnlen;
 
664
                                        ber_len_t       patlen, vdnlen;
600
665
        
601
666
                                        patlen = a->acl_attrval.bv_len;
602
667
                                        vdnlen = val->bv_len;
615
680
                                                        continue;
616
681
        
617
682
                                                rdnlen = dn_rdnlen( NULL, val );
618
 
                                                if ( rdnlen != vdnlen - patlen - 1 )
 
683
                                                if ( rdnlen + patlen + 1 != vdnlen )
619
684
                                                        continue;
620
685
        
621
686
                                        } else if ( a->acl_attrval_style == ACL_STYLE_SUBTREE ) {
648
713
                return a;
649
714
        }
650
715
 
 
716
        if ( !state->as_fe_done ) {
 
717
                state->as_fe_done = 1;
 
718
                a = frontendDB->be_acl;
 
719
                goto retry;
 
720
        }
 
721
 
651
722
        Debug( LDAP_DEBUG_ACL, "<= acl_get: done.\n", 0, 0, 0 );
652
723
        return( NULL );
653
724
}
667
738
acl_mask_dn(
668
739
        Operation               *op,
669
740
        Entry                   *e,
670
 
        AttributeDescription    *desc,
671
741
        struct berval           *val,
672
742
        AccessControl           *a,
673
 
        int                     nmatch,
674
 
        regmatch_t              *matches,
 
743
        AclRegexMatches         *matches,
675
744
        slap_dn_access          *bdn,
676
745
        struct berval           *opndn )
677
746
{
730
799
 
731
800
        } else if ( bdn->a_style == ACL_STYLE_REGEX ) {
732
801
                if ( !ber_bvccmp( &bdn->a_pat, '*' ) ) {
733
 
                        int             tmp_nmatch;
734
 
                        regmatch_t      tmp_matches[2],
735
 
                                        *tmp_matchesp = tmp_matches;
736
 
 
 
802
                        AclRegexMatches tmp_matches,
 
803
                                        *tmp_matchesp = &tmp_matches;
737
804
                        int             rc = 0;
738
 
 
739
 
                        switch ( a->acl_dn_style ) {
 
805
                        regmatch_t      *tmp_data;
 
806
 
 
807
                        MATCHES_MEMSET( &tmp_matches );
 
808
                        tmp_data = &tmp_matches.dn_data[0];
 
809
 
 
810
                        if ( a->acl_attrval_style == ACL_STYLE_REGEX )
 
811
                                tmp_matchesp = matches;
 
812
                        else switch ( a->acl_dn_style ) {
740
813
                        case ACL_STYLE_REGEX:
741
814
                                if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
742
 
                                        tmp_matchesp = matches;
743
 
                                        tmp_nmatch = nmatch;
 
815
                                        tmp_matchesp = matches; 
744
816
                                        break;
745
817
                                }
746
818
                        /* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
747
819
 
748
820
                        case ACL_STYLE_BASE:
749
 
                                tmp_matches[0].rm_so = 0;
750
 
                                tmp_matches[0].rm_eo = e->e_nname.bv_len;
751
 
                                tmp_nmatch = 1;
 
821
                                tmp_data[0].rm_so = 0;
 
822
                                tmp_data[0].rm_eo = e->e_nname.bv_len;
 
823
                                tmp_matches.dn_count = 1;
752
824
                                break;
753
825
 
754
826
                        case ACL_STYLE_ONE:
755
827
                        case ACL_STYLE_SUBTREE:
756
828
                        case ACL_STYLE_CHILDREN:
757
 
                                tmp_matches[0].rm_so = 0;
758
 
                                tmp_matches[0].rm_eo = e->e_nname.bv_len;
759
 
                                tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
760
 
                                tmp_matches[1].rm_eo = e->e_nname.bv_len;
761
 
                                tmp_nmatch = 2;
 
829
                                tmp_data[0].rm_so = 0;
 
830
                                tmp_data[0].rm_eo = e->e_nname.bv_len;
 
831
                                tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
 
832
                                tmp_data[1].rm_eo = e->e_nname.bv_len;
 
833
                                tmp_matches.dn_count = 2;
762
834
                                break;
763
835
 
764
836
                        default:
772
844
                        }
773
845
 
774
846
                        if ( !regex_matches( &bdn->a_pat, opndn->bv_val,
775
 
                                e->e_ndn, tmp_nmatch, tmp_matchesp ) )
 
847
                                &e->e_nname, NULL, tmp_matchesp ) )
776
848
                        {
777
849
                                return 1;
778
850
                        }
790
862
                        struct berval   bv;
791
863
                        char            buf[ACL_BUF_SIZE];
792
864
                        
793
 
                        int             tmp_nmatch;
794
 
                        regmatch_t      tmp_matches[2],
795
 
                                        *tmp_matchesp = tmp_matches;
796
 
 
 
865
                        AclRegexMatches tmp_matches,
 
866
                                        *tmp_matchesp = &tmp_matches;
797
867
                        int             rc = 0;
 
868
                        regmatch_t      *tmp_data;
 
869
 
 
870
                        MATCHES_MEMSET( &tmp_matches );
 
871
                        tmp_data = &tmp_matches.dn_data[0];
798
872
 
799
873
                        bv.bv_len = sizeof( buf ) - 1;
800
874
                        bv.bv_val = buf;
801
875
 
802
 
                        switch ( a->acl_dn_style ) {
 
876
                        /* Expand value regex */
 
877
                        if ( a->acl_attrval_style == ACL_STYLE_REGEX )
 
878
                                tmp_matchesp = matches;
 
879
                        else switch ( a->acl_dn_style ) {
803
880
                        case ACL_STYLE_REGEX:
804
881
                                if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
805
882
                                        tmp_matchesp = matches;
806
 
                                        tmp_nmatch = nmatch;
807
883
                                        break;
808
884
                                }
809
885
                        /* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
810
886
 
811
887
                        case ACL_STYLE_BASE:
812
 
                                tmp_matches[0].rm_so = 0;
813
 
                                tmp_matches[0].rm_eo = e->e_nname.bv_len;
814
 
                                tmp_nmatch = 1;
 
888
                                tmp_data[0].rm_so = 0;
 
889
                                tmp_data[0].rm_eo = e->e_nname.bv_len;
 
890
                                tmp_matches.dn_count = 1;
815
891
                                break;
816
892
 
817
893
                        case ACL_STYLE_ONE:
818
894
                        case ACL_STYLE_SUBTREE:
819
895
                        case ACL_STYLE_CHILDREN:
820
 
                                tmp_matches[0].rm_so = 0;
821
 
                                tmp_matches[0].rm_eo = e->e_nname.bv_len;
822
 
                                tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
823
 
                                tmp_matches[1].rm_eo = e->e_nname.bv_len;
824
 
                                tmp_nmatch = 2;
 
896
                                tmp_data[0].rm_so = 0;
 
897
                                tmp_data[0].rm_eo = e->e_nname.bv_len;
 
898
                                tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
 
899
                                tmp_data[1].rm_eo = e->e_nname.bv_len;
 
900
                                tmp_matches.dn_count = 2;
825
901
                                break;
826
902
 
827
903
                        default:
835
911
                        }
836
912
 
837
913
                        if ( acl_string_expand( &bv, &bdn->a_pat, 
838
 
                                        e->e_nname.bv_val,
839
 
                                        tmp_nmatch, tmp_matchesp ) )
 
914
                                                &e->e_nname, 
 
915
                                                val, tmp_matchesp ) )
840
916
                        {
841
917
                                return 1;
842
918
                        }
946
1022
        Entry                   *e,
947
1023
        struct berval           *val,
948
1024
        AccessControl           *a,
949
 
        Access                  *b,
950
 
        int                     i,
951
 
        regmatch_t              *matches,
952
1025
        int                     count,
953
1026
        AccessControlState      *state,
954
1027
        slap_dn_access          *bdn,
1050
1123
        Entry                   *e,
1051
1124
        AttributeDescription    *desc,
1052
1125
        struct berval           *val,
1053
 
        int                     nmatch,
1054
 
        regmatch_t              *matches,
 
1126
        AclRegexMatches         *matches,
1055
1127
        int                     count,
1056
 
        AccessControlState      *state )
 
1128
        AccessControlState      *state,
 
1129
        slap_access_t   access )
1057
1130
{
1058
1131
        int             i;
1059
1132
        Access          *b;
1061
1134
        char            accessmaskbuf[ACCESSMASK_MAXLEN];
1062
1135
#endif /* DEBUG */
1063
1136
        const char      *attr;
1064
 
        slap_mask_t     a2pmask = ACL_ACCESS2PRIV( *mask );
 
1137
#ifdef SLAP_DYNACL
 
1138
        slap_mask_t     a2pmask = ACL_ACCESS2PRIV( access );
 
1139
#endif /* SLAP_DYNACL */
1065
1140
 
1066
1141
        assert( a != NULL );
1067
1142
        assert( mask != NULL );
1106
1181
                         * is maintained in a_dn_pat.
1107
1182
                         */
1108
1183
 
1109
 
                        if ( acl_mask_dn( op, e, desc, val, a, nmatch, matches,
 
1184
                        if ( acl_mask_dn( op, e, val, a, matches,
1110
1185
                                &b->a_dn, &op->o_ndn ) )
1111
1186
                        {
1112
1187
                                continue;
1137
1212
                                ndn = op->o_ndn;
1138
1213
                        }
1139
1214
 
1140
 
                        if ( acl_mask_dn( op, e, desc, val, a, nmatch, matches,
 
1215
                        if ( acl_mask_dn( op, e, val, a, matches,
1141
1216
                                &b->a_realdn, &ndn ) )
1142
1217
                        {
1143
1218
                                continue;
1153
1228
 
1154
1229
                        if ( !ber_bvccmp( &b->a_sockurl_pat, '*' ) ) {
1155
1230
                                if ( b->a_sockurl_style == ACL_STYLE_REGEX) {
1156
 
                                        if (!regex_matches( &b->a_sockurl_pat, op->o_conn->c_listener_url.bv_val,
1157
 
                                                        e->e_ndn, nmatch, matches ) ) 
 
1231
                                        if ( !regex_matches( &b->a_sockurl_pat, op->o_conn->c_listener_url.bv_val,
 
1232
                                                        &e->e_nname, val, matches ) ) 
1158
1233
                                        {
1159
1234
                                                continue;
1160
1235
                                        }
1165
1240
 
1166
1241
                                        bv.bv_len = sizeof( buf ) - 1;
1167
1242
                                        bv.bv_val = buf;
1168
 
                                        if ( acl_string_expand( &bv, &b->a_sockurl_pat,
1169
 
                                                        e->e_ndn, nmatch, matches ) )
 
1243
                                        if ( acl_string_expand( &bv, &b->a_sockurl_pat, &e->e_nname, val, matches ) )
1170
1244
                                        {
1171
1245
                                                continue;
1172
1246
                                        }
1193
1267
                                b->a_domain_pat.bv_val, 0, 0 );
1194
1268
                        if ( !ber_bvccmp( &b->a_domain_pat, '*' ) ) {
1195
1269
                                if ( b->a_domain_style == ACL_STYLE_REGEX) {
1196
 
                                        if (!regex_matches( &b->a_domain_pat, op->o_conn->c_peer_domain.bv_val,
1197
 
                                                        e->e_ndn, nmatch, matches ) ) 
 
1270
                                        if ( !regex_matches( &b->a_domain_pat, op->o_conn->c_peer_domain.bv_val,
 
1271
                                                        &e->e_nname, val, matches ) ) 
1198
1272
                                        {
1199
1273
                                                continue;
1200
1274
                                        }
1210
1284
                                                bv.bv_len = sizeof(buf) - 1;
1211
1285
                                                bv.bv_val = buf;
1212
1286
 
1213
 
                                                if ( acl_string_expand(&bv, &b->a_domain_pat,
1214
 
                                                                e->e_ndn, nmatch, matches) )
 
1287
                                                if ( acl_string_expand(&bv, &b->a_domain_pat, &e->e_nname, val, matches) )
1215
1288
                                                {
1216
1289
                                                        continue;
1217
1290
                                                }
1248
1321
                                b->a_peername_pat.bv_val, 0, 0 );
1249
1322
                        if ( !ber_bvccmp( &b->a_peername_pat, '*' ) ) {
1250
1323
                                if ( b->a_peername_style == ACL_STYLE_REGEX ) {
1251
 
                                        if (!regex_matches( &b->a_peername_pat, op->o_conn->c_peer_name.bv_val,
1252
 
                                                        e->e_ndn, nmatch, matches ) ) 
 
1324
                                        if ( !regex_matches( &b->a_peername_pat, op->o_conn->c_peer_name.bv_val,
 
1325
                                                        &e->e_nname, val, matches ) ) 
1253
1326
                                        {
1254
1327
                                                continue;
1255
1328
                                        }
1267
1340
 
1268
1341
                                                bv.bv_len = sizeof( buf ) - 1;
1269
1342
                                                bv.bv_val = buf;
1270
 
                                                if ( acl_string_expand( &bv, &b->a_peername_pat,
1271
 
                                                                e->e_ndn, nmatch, matches ) )
 
1343
                                                if ( acl_string_expand( &bv, &b->a_peername_pat, &e->e_nname, val, matches ) )
1272
1344
                                                {
1273
1345
                                                        continue;
1274
1346
                                                }
1401
1473
                                b->a_sockname_pat.bv_val, 0, 0 );
1402
1474
                        if ( !ber_bvccmp( &b->a_sockname_pat, '*' ) ) {
1403
1475
                                if ( b->a_sockname_style == ACL_STYLE_REGEX) {
1404
 
                                        if (!regex_matches( &b->a_sockname_pat, op->o_conn->c_sock_name.bv_val,
1405
 
                                                        e->e_ndn, nmatch, matches ) ) 
 
1476
                                        if ( !regex_matches( &b->a_sockname_pat, op->o_conn->c_sock_name.bv_val,
 
1477
                                                        &e->e_nname, val, matches ) ) 
1406
1478
                                        {
1407
1479
                                                continue;
1408
1480
                                        }
1413
1485
 
1414
1486
                                        bv.bv_len = sizeof( buf ) - 1;
1415
1487
                                        bv.bv_val = buf;
1416
 
                                        if ( acl_string_expand( &bv, &b->a_sockname_pat,
1417
 
                                                        e->e_ndn, nmatch, matches ) )
 
1488
                                        if ( acl_string_expand( &bv, &b->a_sockname_pat, &e->e_nname, val, matches ) )
1418
1489
                                        {
1419
1490
                                                continue;
1420
1491
                                        }
1432
1503
                }
1433
1504
 
1434
1505
                if ( b->a_dn_at != NULL ) {
1435
 
                        if ( acl_mask_dnattr( op, e, val, a, b, i,
1436
 
                                        matches, count, state,
 
1506
                        if ( acl_mask_dnattr( op, e, val, a,
 
1507
                                        count, state,
1437
1508
                                        &b->a_dn, &op->o_ndn ) )
1438
1509
                        {
1439
1510
                                continue;
1450
1521
                                ndn = op->o_ndn;
1451
1522
                        }
1452
1523
 
1453
 
                        if ( acl_mask_dnattr( op, e, val, a, b, i,
1454
 
                                        matches, count, state,
 
1524
                        if ( acl_mask_dnattr( op, e, val, a,
 
1525
                                        count, state,
1455
1526
                                        &b->a_realdn, &ndn ) )
1456
1527
                        {
1457
1528
                                continue;
1477
1548
                        /* see if asker is listed in dnattr */
1478
1549
                        if ( b->a_group_style == ACL_STYLE_EXPAND ) {
1479
1550
                                char            buf[ACL_BUF_SIZE];
1480
 
                                int             tmp_nmatch;
1481
 
                                regmatch_t      tmp_matches[2],
1482
 
                                                *tmp_matchesp = tmp_matches;
 
1551
                                AclRegexMatches tmp_matches,
 
1552
                                                *tmp_matchesp = &tmp_matches;
 
1553
                                regmatch_t      *tmp_data;
 
1554
 
 
1555
                                MATCHES_MEMSET( &tmp_matches );
 
1556
                                tmp_data = &tmp_matches.dn_data[0];
1483
1557
 
1484
1558
                                bv.bv_len = sizeof(buf) - 1;
1485
1559
                                bv.bv_val = buf;
1486
1560
 
1487
1561
                                rc = 0;
1488
1562
 
1489
 
                                switch ( a->acl_dn_style ) {
 
1563
                                if ( a->acl_attrval_style == ACL_STYLE_REGEX )
 
1564
                                        tmp_matchesp = matches;
 
1565
                                else switch ( a->acl_dn_style ) {
1490
1566
                                case ACL_STYLE_REGEX:
1491
1567
                                        if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
1492
1568
                                                tmp_matchesp = matches;
1493
 
                                                tmp_nmatch = nmatch;
1494
1569
                                                break;
1495
1570
                                        }
1496
1571
 
1497
1572
                                /* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
1498
1573
                                case ACL_STYLE_BASE:
1499
 
                                        tmp_matches[0].rm_so = 0;
1500
 
                                        tmp_matches[0].rm_eo = e->e_nname.bv_len;
1501
 
                                        tmp_nmatch = 1;
 
1574
                                        tmp_data[0].rm_so = 0;
 
1575
                                        tmp_data[0].rm_eo = e->e_nname.bv_len;
 
1576
                                        tmp_matches.dn_count = 1;
1502
1577
                                        break;
1503
1578
 
1504
1579
                                case ACL_STYLE_ONE:
1505
1580
                                case ACL_STYLE_SUBTREE:
1506
1581
                                case ACL_STYLE_CHILDREN:
1507
 
                                        tmp_matches[0].rm_so = 0;
1508
 
                                        tmp_matches[0].rm_eo = e->e_nname.bv_len;
1509
 
                                        tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
1510
 
                                        tmp_matches[1].rm_eo = e->e_nname.bv_len;
1511
 
                                        tmp_nmatch = 2;
 
1582
                                        tmp_data[0].rm_so = 0;
 
1583
                                        tmp_data[0].rm_eo = e->e_nname.bv_len;
 
1584
 
 
1585
                                        tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
 
1586
                                        tmp_data[1].rm_eo = e->e_nname.bv_len;
 
1587
                                        tmp_matches.dn_count = 2;
1512
1588
                                        break;
1513
1589
 
1514
1590
                                default:
1522
1598
                                }
1523
1599
                                
1524
1600
                                if ( acl_string_expand( &bv, &b->a_group_pat,
1525
 
                                                e->e_nname.bv_val,
1526
 
                                                tmp_nmatch, tmp_matchesp ) )
 
1601
                                                &e->e_nname, val,
 
1602
                                                tmp_matchesp ) )
1527
1603
                                {
1528
1604
                                        continue;
1529
1605
                                }
1561
1637
                                b->a_set_pat.bv_val, 0, 0 );
1562
1638
 
1563
1639
                        if ( b->a_set_style == ACL_STYLE_EXPAND ) {
1564
 
                                int             tmp_nmatch;
1565
 
                                regmatch_t      tmp_matches[2],
1566
 
                                                *tmp_matchesp = tmp_matches;
 
1640
                                AclRegexMatches tmp_matches,
 
1641
                                                *tmp_matchesp = &tmp_matches;
1567
1642
                                int             rc = 0;
 
1643
                                regmatch_t      *tmp_data;
 
1644
 
 
1645
                                MATCHES_MEMSET( &tmp_matches );
 
1646
                                tmp_data = &tmp_matches.dn_data[0];
1568
1647
 
1569
1648
                                bv.bv_len = sizeof( buf ) - 1;
1570
1649
                                bv.bv_val = buf;
1571
1650
 
1572
1651
                                rc = 0;
1573
1652
 
1574
 
                                switch ( a->acl_dn_style ) {
 
1653
                                if ( a->acl_attrval_style == ACL_STYLE_REGEX )
 
1654
                                        tmp_matchesp = matches;
 
1655
                                else switch ( a->acl_dn_style ) {
1575
1656
                                case ACL_STYLE_REGEX:
1576
1657
                                        if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
1577
1658
                                                tmp_matchesp = matches;
1578
 
                                                tmp_nmatch = nmatch;
1579
1659
                                                break;
1580
1660
                                        }
1581
1661
 
1582
1662
                                /* FALLTHRU: applies also to ACL_STYLE_REGEX when pattern is "*" */
1583
1663
                                case ACL_STYLE_BASE:
1584
 
                                        tmp_matches[0].rm_so = 0;
1585
 
                                        tmp_matches[0].rm_eo = e->e_nname.bv_len;
1586
 
                                        tmp_nmatch = 1;
 
1664
                                        tmp_data[0].rm_so = 0;
 
1665
                                        tmp_data[0].rm_eo = e->e_nname.bv_len;
 
1666
                                        tmp_matches.dn_count = 1;
1587
1667
                                        break;
1588
1668
 
1589
1669
                                case ACL_STYLE_ONE:
1590
1670
                                case ACL_STYLE_SUBTREE:
1591
1671
                                case ACL_STYLE_CHILDREN:
1592
 
                                        tmp_matches[0].rm_so = 0;
1593
 
                                        tmp_matches[0].rm_eo = e->e_nname.bv_len;
1594
 
                                        tmp_matches[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
1595
 
                                        tmp_matches[1].rm_eo = e->e_nname.bv_len;
1596
 
                                        tmp_nmatch = 2;
 
1672
                                        tmp_data[0].rm_so = 0;
 
1673
                                        tmp_data[0].rm_eo = e->e_nname.bv_len;
 
1674
                                        tmp_data[1].rm_so = e->e_nname.bv_len - a->acl_dn_pat.bv_len;
 
1675
                                        tmp_data[1].rm_eo = e->e_nname.bv_len; tmp_matches.dn_count = 2;
1597
1676
                                        break;
1598
1677
 
1599
1678
                                default:
1607
1686
                                }
1608
1687
                                
1609
1688
                                if ( acl_string_expand( &bv, &b->a_set_pat,
1610
 
                                                e->e_nname.bv_val,
1611
 
                                                tmp_nmatch, tmp_matchesp ) )
 
1689
                                                &e->e_nname, val,
 
1690
                                                tmp_matchesp ) )
1612
1691
                                {
1613
1692
                                        continue;
1614
1693
                                }
1720
1799
                                Debug( LDAP_DEBUG_ACL, "    <= check a_dynacl: %s\n",
1721
1800
                                        da->da_name, 0, 0 );
1722
1801
 
 
1802
                                /*
 
1803
                                 * XXXmanu Only DN matches are supplied 
 
1804
                                 * sending attribute values matches require
 
1805
                                 * an API update
 
1806
                                 */
1723
1807
                                (void)da->da_mask( da->da_private, op, e, desc,
1724
 
                                        val, nmatch, matches, &grant, &deny );
 
1808
                                        val, matches->dn_count, matches->dn_data, 
 
1809
                                        &grant, &deny ); 
1725
1810
 
1726
1811
                                tgrant |= grant;
1727
1812
                                tdeny |= deny;
1790
1875
                        *mask = modmask;
1791
1876
                }
1792
1877
 
1793
 
                a2pmask = *mask;
1794
 
 
1795
1878
                Debug( LDAP_DEBUG_ACL,
1796
1879
                        "<= acl_mask: [%d] mask: %s\n",
1797
1880
                        i, accessmask2str(*mask, accessmaskbuf, 1), 0 );
1843
1926
        }
1844
1927
        assert( be != NULL );
1845
1928
 
 
1929
        /* If ADD attribute checking is not enabled, just allow it */
 
1930
        if ( op->o_tag == LDAP_REQ_ADD && !SLAP_DBACL_ADD( be ))
 
1931
                return 1;
 
1932
 
1846
1933
        /* short circuit root database access */
1847
1934
        if ( be_isroot( op ) ) {
1848
1935
                Debug( LDAP_DEBUG_ACL,
1852
1939
        }
1853
1940
 
1854
1941
        /* use backend default access if no backend acls */
1855
 
        if( op->o_bd != NULL && op->o_bd->be_acl == NULL ) {
 
1942
        if( op->o_bd != NULL && op->o_bd->be_acl == NULL && frontendDB->be_acl == NULL ) {
1856
1943
                Debug( LDAP_DEBUG_ACL,
1857
1944
                        "=> access_allowed: backend default %s access %s to \"%s\"\n",
1858
1945
                        access2str( ACL_WRITE ),
2114
2201
        if ( rc != LDAP_SUCCESS ) {
2115
2202
                Debug( LDAP_DEBUG_TRACE,
2116
2203
                        "%s acl_set_gather: DN=\"%s\" normalize failed\n",
2117
 
                        cp->asc_op->o_log_prefix, op2.o_req_dn.bv_val, 0 );
 
2204
                        cp->asc_op->o_log_prefix, ludp->lud_dn, 0 );
2118
2205
 
2119
2206
                goto url_done;
2120
2207
        }
2211
2298
 
2212
2299
url_done:;
2213
2300
        if ( op2.ors_filter && op2.ors_filter != slap_filter_objectClass_pres ) {
2214
 
                filter_free_x( cp->asc_op, op2.ors_filter );
 
2301
                filter_free_x( cp->asc_op, op2.ors_filter, 1 );
2215
2302
        }
2216
2303
        if ( !BER_BVISNULL( &op2.o_req_ndn ) ) {
2217
2304
                slap_sl_free( op2.o_req_ndn.bv_val, cp->asc_op->o_tmpmemctx );
2275
2362
        AclSetCookie    cookie;
2276
2363
 
2277
2364
        if ( default_set_attribute == NULL ) {
2278
 
                ber_dupbv_x( &set, subj, op->o_tmpmemctx );
 
2365
                set = *subj;
2279
2366
 
2280
2367
        } else {
2281
2368
                struct berval           subjdn, ndn = BER_BVNULL;
2324
2411
                        acl_set_gather,
2325
2412
                        (SetCookie *)&cookie, &set,
2326
2413
                        &op->o_ndn, &e->e_nname, NULL ) > 0 );
2327
 
                slap_sl_free( set.bv_val, op->o_tmpmemctx );
 
2414
                if ( set.bv_val != subj->bv_val ) {
 
2415
                        slap_sl_free( set.bv_val, op->o_tmpmemctx );
 
2416
                }
2328
2417
        }
2329
2418
 
2330
2419
        return(rc);
2420
2509
acl_string_expand(
2421
2510
        struct berval   *bv,
2422
2511
        struct berval   *pat,
2423
 
        char            *match,
2424
 
        int             nmatch,
2425
 
        regmatch_t      *matches)
 
2512
        struct berval   *dn_matches,
 
2513
        struct berval   *val_matches,
 
2514
        AclRegexMatches *matches)
2426
2515
{
2427
2516
        ber_len_t       size;
2428
2517
        char   *sp;
2429
2518
        char   *dp;
2430
2519
        int     flag;
 
2520
        enum { DN_FLAG, VAL_FLAG } tflag;
2431
2521
 
2432
2522
        size = 0;
2433
2523
        bv->bv_val[0] = '\0';
2434
2524
        bv->bv_len--; /* leave space for lone $ */
2435
2525
 
2436
2526
        flag = 0;
 
2527
        tflag = DN_FLAG;
2437
2528
        for ( dp = bv->bv_val, sp = pat->bv_val; size < bv->bv_len &&
2438
2529
                sp < pat->bv_val + pat->bv_len ; sp++ )
2439
2530
        {
2443
2534
                                *dp++ = '$';
2444
2535
                                size++;
2445
2536
                                flag = 0;
 
2537
                                tflag = DN_FLAG;
 
2538
 
 
2539
                        } else if ( flag == 2 && *sp == 'v' /*'}'*/) {
 
2540
                                tflag = VAL_FLAG;
 
2541
 
 
2542
                        } else if ( flag == 2 && *sp == 'd' /*'}'*/) {
 
2543
                                tflag = DN_FLAG;
2446
2544
 
2447
2545
                        } else if ( flag == 1 && *sp == '{' /*'}'*/) {
2448
2546
                                flag = 2;
2449
2547
 
2450
2548
                        } else if ( *sp >= '0' && *sp <= '9' ) {
 
2549
                                int     nm;
 
2550
                                regmatch_t *m;
 
2551
                                char *data;
2451
2552
                                int     n;
2452
2553
                                int     i;
2453
2554
                                int     l;
2467
2568
                                        }
2468
2569
                                }
2469
2570
 
2470
 
                                if ( n >= nmatch ) {
 
2571
                                switch (tflag) {
 
2572
                                case DN_FLAG:
 
2573
                                        nm = matches->dn_count;
 
2574
                                        m = matches->dn_data;
 
2575
                                        data = dn_matches ? dn_matches->bv_val : NULL;
 
2576
                                        break;
 
2577
                                case VAL_FLAG:
 
2578
                                        nm = matches->val_count;
 
2579
                                        m = matches->val_data;
 
2580
                                        data = val_matches ? val_matches->bv_val : NULL;
 
2581
                                        break;
 
2582
                                default:
 
2583
                                        assert( 0 );
 
2584
                                }
 
2585
                                if ( n >= nm ) {
 
2586
                                        /* FIXME: error */
 
2587
                                        return 1;
 
2588
                                }
 
2589
                                if ( data == NULL ) {
2471
2590
                                        /* FIXME: error */
2472
2591
                                        return 1;
2473
2592
                                }
2474
2593
                                
2475
2594
                                *dp = '\0';
2476
 
                                i = matches[n].rm_so;
2477
 
                                l = matches[n].rm_eo; 
 
2595
                                i = m[n].rm_so;
 
2596
                                l = m[n].rm_eo; 
 
2597
                                        
2478
2598
                                for ( ; size < bv->bv_len && i < l; size++, i++ ) {
2479
 
                                        *dp++ = match[i];
 
2599
                                        *dp++ = data[i];
2480
2600
                                }
2481
2601
                                *dp = '\0';
2482
2602
 
2483
2603
                                flag = 0;
 
2604
                                tflag = DN_FLAG;
2484
2605
                        }
2485
2606
                } else {
2486
2607
                        if (*sp == '$') {
2501
2622
        *dp = '\0';
2502
2623
        bv->bv_len = size;
2503
2624
 
2504
 
        Debug( LDAP_DEBUG_TRACE, "=> acl_string_expand: pattern:  %.*s\n", (int)pat->bv_len, pat->bv_val, 0 );
2505
 
        Debug( LDAP_DEBUG_TRACE, "=> acl_string_expand: expanded: %s\n", bv->bv_val, 0, 0 );
 
2625
        Debug( LDAP_DEBUG_ACL, "=> acl_string_expand: pattern:  %.*s\n", (int)pat->bv_len, pat->bv_val, 0 );
 
2626
        Debug( LDAP_DEBUG_ACL, "=> acl_string_expand: expanded: %s\n", bv->bv_val, 0, 0 );
2506
2627
 
2507
2628
        return 0;
2508
2629
}
2511
2632
regex_matches(
2512
2633
        struct berval   *pat,           /* pattern to expand and match against */
2513
2634
        char            *str,           /* string to match against pattern */
2514
 
        char            *buf,           /* buffer with $N expansion variables */
2515
 
        int             nmatch, /* size of the matches array */
2516
 
        regmatch_t      *matches        /* offsets in buffer for $N expansion variables */
 
2635
        struct berval   *dn_matches,    /* buffer with $N expansion variables from DN */
 
2636
        struct berval   *val_matches,   /* buffer with $N expansion variables from val */
 
2637
        AclRegexMatches *matches        /* offsets in buffer for $N expansion variables */
2517
2638
)
2518
2639
{
2519
2640
        regex_t re;
2528
2649
                str = "";
2529
2650
        };
2530
2651
 
2531
 
        acl_string_expand( &bv, pat, buf, nmatch, matches );
 
2652
        acl_string_expand( &bv, pat, dn_matches, val_matches, matches );
2532
2653
        rc = regcomp( &re, newbuf, REG_EXTENDED|REG_ICASE );
2533
2654
        if ( rc ) {
2534
2655
                char error[ACL_BUF_SIZE];